diff --git a/botocore/parsers.py b/botocore/parsers.py
index 0c7a34f218..7393fb51dd 100644
--- a/botocore/parsers.py
+++ b/botocore/parsers.py
@@ -124,6 +124,7 @@
from botocore.compat import ETree, XMLParseError
from botocore.eventstream import EventStream, NoInitialResponseError
from botocore.utils import (
+ ensure_boolean,
is_json_value_header,
lowercase_dict,
merge_dicts,
@@ -201,6 +202,10 @@ class ResponseParser:
DEFAULT_ENCODING = 'utf-8'
EVENT_STREAM_PARSER_CLS = None
+ # This is a list of known values for the "location" key in the
+ # serialization dict. The location key tells us where in the response
+ # to parse the value. Locations not in this list will be ignored.
+ KNOWN_LOCATIONS = ('statusCode', 'header', 'headers')
def __init__(self, timestamp_parser=None, blob_parser=None):
if timestamp_parser is None:
@@ -356,6 +361,9 @@ def _has_unknown_tagged_union_member(self, shape, value):
if shape.is_tagged_union:
cleaned_value = value.copy()
cleaned_value.pop("__type", None)
+ cleaned_value = {
+ k: v for k, v in cleaned_value.items() if v is not None
+ }
if len(cleaned_value) != 1:
error_msg = (
"Invalid service response: %s must have one and only "
@@ -363,7 +371,11 @@ def _has_unknown_tagged_union_member(self, shape, value):
)
raise ResponseParserError(error_msg % shape.name)
tag = self._get_first_key(cleaned_value)
- if tag not in shape.members:
+ serialized_member_names = [
+ shape.members[member].serialization.get('name', member)
+ for member in shape.members
+ ]
+ if tag not in serialized_member_names:
msg = (
"Received a tagged union response with member "
"unknown to client: %s. Please upgrade SDK for full "
@@ -427,11 +439,12 @@ def _handle_structure(self, shape, node):
return self._handle_unknown_tagged_union_member(tag)
for member_name in members:
member_shape = members[member_name]
+ location = member_shape.serialization.get('location')
if (
- 'location' in member_shape.serialization
+ location in self.KNOWN_LOCATIONS
or member_shape.serialization.get('eventheader')
):
- # All members with locations have already been handled,
+ # All members with known locations have already been handled,
# so we don't need to parse these members.
continue
xml_name = self._member_key_name(member_shape, member_name)
@@ -707,6 +720,8 @@ def _do_error_parse(self, response, shape):
# code has a couple forms as well:
# * "com.aws.dynamodb.vAPI#ProvisionedThroughputExceededException"
# * "ResourceNotFoundException"
+ if ':' in code:
+ code = code.split(':', 1)[0]
if '#' in code:
code = code.rsplit('#', 1)[1]
if 'x-amzn-query-error' in headers:
@@ -1020,19 +1035,29 @@ def _inject_error_code(self, error, response):
# The "Code" value can come from either a response
# header or a value in the JSON body.
body = self._initial_body_parse(response['body'])
+ code = None
if 'x-amzn-errortype' in response['headers']:
code = response['headers']['x-amzn-errortype']
- # Could be:
- # x-amzn-errortype: ValidationException:
- code = code.split(':')[0]
- error['Error']['Code'] = code
elif 'code' in body or 'Code' in body:
- error['Error']['Code'] = body.get('code', body.get('Code', ''))
+ code = body.get('code', body.get('Code', ''))
+ if code is not None:
+ if ':' in code:
+ code = code.split(':', 1)[0]
+ if '#' in code:
+ code = code.rsplit('#', 1)[1]
+ error['Error']['Code'] = code
+
+ def _handle_boolean(self, shape, value):
+ return ensure_boolean(value)
def _handle_integer(self, shape, value):
return int(value)
+ def _handle_float(self, shape, value):
+ return float(value)
+
_handle_long = _handle_integer
+ _handle_double = _handle_float
class RestXMLParser(BaseRestParser, BaseXMLResponseParser):
diff --git a/tests/unit/protocols/output/ec2.json b/tests/unit/protocols/output/ec2.json
index fa21de0ace..0a52651d08 100644
--- a/tests/unit/protocols/output/ec2.json
+++ b/tests/unit/protocols/output/ec2.json
@@ -1,612 +1,1847 @@
[
- {
- "description": "Scalar members",
- "metadata": {
- "protocol": "ec2"
- },
- "shapes": {
- "OutputShape": {
- "type": "structure",
- "members": {
- "Str": {
- "shape": "StringType"
- },
- "Num": {
- "shape": "IntegerType",
- "locationName": "FooNum"
- },
- "FalseBool": {
- "shape": "BooleanType"
- },
- "TrueBool": {
- "shape": "BooleanType"
- },
- "Float": {
- "shape": "FloatType"
- },
- "Double": {
- "shape": "DoubleType"
- },
- "Long": {
- "shape": "LongType"
- },
- "Char": {
- "shape": "CharType"
- }
- }
- },
- "StringType": {
- "type": "string"
- },
- "IntegerType": {
- "type": "integer"
- },
- "BooleanType": {
- "type": "boolean"
- },
- "FloatType": {
- "type": "float"
- },
- "DoubleType": {
- "type": "double"
- },
- "LongType": {
- "type": "long"
- },
- "CharType": {
- "type": "character"
- }
- },
- "cases": [
- {
- "given": {
- "output": {
- "shape": "OutputShape"
- },
- "name": "OperationName"
- },
- "result": {
- "Str": "myname",
- "Num": 123,
- "FalseBool": false,
- "TrueBool": true,
- "Float": 1.2,
- "Double": 1.3,
- "Long": 200,
- "Char": "a"
- },
- "response": {
- "status_code": 200,
- "headers": {},
- "body": "
The example tests how requests and responses are serialized when there's no request or response members.
While this should be rare, code generators must support this.
" + }, + "description": "Empty output", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "This operation has three possible return values:
This error is thrown when an invalid greeting value is provided.
", + "exception": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "Ec2InvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
InvalidGreeting
\n This error is thrown when a request is invalid.
", + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "Ec2ComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
ComplexError
\n The xmlName trait on the output structure is ignored in AWS Query.
The wrapping element is always operation name + "Response".
" + }, + "description": "The xmlName trait on the output structure is ignored in the ec2 protocol", + "result": { + "foo": "bar" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "The example tests how requests and responses are serialized when there's no request payload or response members.
While this should be rare, code generators must support this.
" + }, + "description": "Empty output", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "Recursive shapes
" + }, + "description": "Serializes recursive structures", + "result": { + "nested": { + "foo": "Foo1", + "nested": { + "bar": "Bar1", + "recursiveMember": { + "foo": "Foo2", + "nested": { + "bar": "Bar2" + } + } + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "Blobs are base64 encoded
" + }, + "description": "Blobs are base64 encoded", + "result": { + "data": "value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "A list of lists of strings.
" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "Ec2XmlEmptyLists", + "given": { + "name": "XmlEmptyLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlListsOutput" + } + }, + "description": "Deserializes empty XML lists", + "result": { + "stringList": [], + "stringSet": [] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "This example serializes enums as top level properties, in lists, sets, and maps.
" + }, + "description": "Serializes simple scalar properties", + "result": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "This example serializes intEnums as top level properties, in lists, sets, and maps.
" + }, + "description": "Serializes simple scalar properties", + "result": { + "intEnum1": 1, + "intEnum2": 2, + "intEnum3": 3, + "intEnumList": [ + 1, + 2 + ], + "intEnumSet": [ + 1, + 2 + ], + "intEnumMap": { + "a": 1, + "b": 2 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "A list of lists of strings.
" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "Ec2XmlLists", + "given": { + "name": "XmlLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlListsOutput" + }, + "documentation": "This test case serializes XML lists for the following cases for both input and output:
ExceptionShape
OtherExceptionShape
UndefinedShape
This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Tests how normal timestamps are serialized", + "result": { + "normal": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of date-time works like normal timestamps", + "result": { + "dateTime": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "result": { + "dateTimeOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of epoch-seconds works", + "result": { + "epochSeconds": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "result": { + "epochSecondsOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of http-date works", + "result": { + "httpDate": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of http-date on the target shape works", + "result": { + "httpDateOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml;charset=UTF-8" + }, + "body": "This error is thrown when an invalid greeting value is provided.
", + "exception": true + }, + "String": { + "type": "string" + } }, - "value": { - "shape": "NumberList" - } - }, - "StringType": { - "type": "string" - }, - "NumberList": { - "type": "list", - "member": { - "shape": "IntegerType" - } - }, - "IntegerType": { - "type": "integer" - } + "cases": [ + { + "id": "AwsJson11InvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "InvalidGreeting" + } + ] + }, + "description": "Parses simple JSON errors", + "errorCode": "InvalidGreeting", + "errorMessage": "Hi", + "error": { + "Message": "Hi" + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"InvalidGreeting\",\n \"Message\": \"Hi\"\n}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "MapMember": { - "a": [1, 2], - "b": [3, 4] - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"MapMember\": {\"a\": [1, 2], \"b\": [3, 4]}}" - } - } - ] - }, - { - "description": "Ignores extra data", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "StrType": { - "shape": "StrType" - } - } - }, - "StrType": { - "type": "string" - } - }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + "shapes": { + "ComplexError": { + "type": "structure", + "members": { + "TopLevel": { + "shape": "String" + }, + "Nested": { + "shape": "ComplexNestedErrorData" + } + }, + "documentation": "This error is thrown when a request is invalid.
", + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + } + } + } }, - "result": {}, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"foo\": \"bar\"}" - } - } - ] - }, - { - "description": "RPC JSON Event Stream", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Payload": {"shape": "EventStream"}, - "InitialResponse": {"shape": "StringType"} - } - }, - "EventStream": { - "type": "structure", - "eventstream": true, - "members": { - "TypeA": {"shape": "TypeAEvent"}, - "TypeB": {"shape": "TypeBEvent"} - } - }, - "TypeAEvent": { - "type": "structure", - "event": true, - "members": { - "Payload": { - "shape": "BlobType", - "eventpayload": true - } - } - }, - "TypeBEvent": { - "type": "structure", - "event": true, - "members": { - "Details": { - "shape": "Details", - "eventpayload": true - } - } - }, - "Details": { - "type": "structure", - "members": { - "StringField": {"shape": "StringType"}, - "IntegerField": {"shape": "IntegerType"} - } - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - }, - "BlobType": { - "type": "blob" - } + "cases": [ + { + "id": "AwsJson11ComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "description": "Parses a complex error with no message member", + "errorCode": "ComplexError", + "error": { + "TopLevel": "Top level", + "Nested": { + "Foo": "bar" + } + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"ComplexError\",\n \"TopLevel\": \"Top level\",\n \"Nested\": {\n \"Foo\": \"bar\"\n }\n}" + } + }, + { + "id": "AwsJson11EmptyComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "errorCode": "ComplexError", + "error": {}, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"ComplexError\"\n}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "InitialResponse": "sometext", - "Payload": [ - { - "TypeA": {"Payload": "somebytes"} - }, - { - "TypeB": { - "Details": { - "StringField": "somestring", - "IntegerField": 123 - } - } - } - ] + "shapes": { + "FooError": { + "type": "structure", + "members": {}, + "documentation": "This error has test cases that test some of the dark corners of Amazon service framework history. It should only be implemented by clients.
", + "exception": true, + "fault": true + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "AAAAfgAAAE/Fo93GDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAEGluaXRpYWwtcmVzcG9uc2UNOmNvbnRlbnQtdHlwZQcACXRleHQvanNvbnsiSW5pdGlhbFJlc3BvbnNlIjogInNvbWV0ZXh0In32mCSDAAAAbAAAAFPLgkVrDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcABVR5cGVBDTpjb250ZW50LXR5cGUHABhhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1zb21lYnl0ZXMesj2HAAAAhgAAAEQqNR/SDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcABVR5cGVCDTpjb250ZW50LXR5cGUHAAl0ZXh0L2pzb257IlN0cmluZ0ZpZWxkIjogInNvbWVzdHJpbmciLCAiSW50ZWdlckZpZWxkIjogMTIzfffGN30=" - } - } - ] - }, - { - "description": "Modeled exceptions", - "metadata": { - "protocol": "json" - }, - "shapes": { - "ExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - }, - "Code": { - "shape": "StringType" - }, - "Message": { - "shape": "StringType" - } - } - }, - "OtherExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "AwsJson11FooErrorUsingXAmznErrorType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Serializes the X-Amzn-ErrorType header. For an example service, see Amazon EKS.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "FooError" + } + } + }, + { + "id": "AwsJson11FooErrorUsingXAmznErrorTypeWithUri", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some X-Amzn-Errortype headers contain URLs. Clients need to split the URL on ':' and take only the first half of the string. For example, 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/'\nis to be interpreted as 'ValidationException'.\n\nFor an example service see Amazon Polly.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "AwsJson11FooErrorUsingXAmznErrorTypeWithUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "X-Amzn-Errortype might contain a URL and a namespace. Client should extract only the shape name. This is a pathalogical case that might not actually happen in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "AwsJson11FooErrorUsingCode", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "This example uses the 'code' property in the output rather than X-Amzn-Errortype. Some services do this though it's preferable to send the X-Amzn-Errortype. Client implementations must first check for the X-Amzn-Errortype and then check for a top-level 'code' property.\n\nFor example service see Amazon S3 Glacier.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"code\": \"FooError\"\n}" + } + }, + { + "id": "AwsJson11FooErrorUsingCodeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"code\": \"aws.protocoltests.restjson#FooError\"\n}" + } + }, + { + "id": "AwsJson11FooErrorUsingCodeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"code\": \"aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + }, + { + "id": "AwsJson11FooErrorWithDunderType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"FooError\"\n}" + } + }, + { + "id": "AwsJson11FooErrorWithDunderTypeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"aws.protocoltests.restjson#FooError\"\n}" + } + }, + { + "id": "AwsJson11FooErrorWithDunderTypeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"__type\": \"aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + } + ] }, - "cases": [ - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" + { + "description": "Test cases for JsonEnums operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "error": { - "BodyMember": "mybody", - "Code": "OtherExceptionShape", - "Message": "mymessage" - }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "{ \"__type\": \"ExceptionShape\", \"Code\": \"OtherExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "BodyMember": "mybody" - }, - "errorCode": "OtherExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "{ \"__type\": \"OtherExceptionShape\", \"Code\": \"ExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" + "shapes": { + "JsonEnumsInputOutput": { + "type": "structure", + "members": { + "fooEnum1": { + "shape": "FooEnum" + }, + "fooEnum2": { + "shape": "FooEnum" + }, + "fooEnum3": { + "shape": "FooEnum" + }, + "fooEnumList": { + "shape": "FooEnumList" + }, + "fooEnumSet": { + "shape": "FooEnumSet" + }, + "fooEnumMap": { + "shape": "FooEnumMap" + } + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumSet": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "String": { + "type": "string" + } }, - "error": {}, - "errorCode": "UndefinedShape", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc" - }, - "body": "{ \"__type\": \"UndefinedShape\", \"Code\": \"ExceptionShape\", \"BodyMember\": \"mybody\"}" - } - } - ] - }, - { - "description": "Modeled exceptions with jsonVersion 1.0", - "metadata": { - "protocol": "json", - "jsonVersion": "1.0" - }, - "shapes": { - "ExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - }, - "Message": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + "cases": [ + { + "id": "AwsJson11Enums", + "given": { + "name": "JsonEnums", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonEnumsInputOutput" + }, + "documentation": "This example serializes enums as top level properties, in lists, sets, and maps.
", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"fooEnum1\": \"Foo\",\n \"fooEnum2\": \"0\",\n \"fooEnum3\": \"1\",\n \"fooEnumList\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumSet\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumMap\": {\n \"hi\": \"Foo\",\n \"zero\": \"0\"\n }\n}" + } + } + ] }, - "cases": [ - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" + { + "description": "Test cases for JsonIntEnums operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "error": { - "BodyMember": "mybody", - "Message": "mymessage" + "shapes": { + "JsonIntEnumsInputOutput": { + "type": "structure", + "members": { + "intEnum1": { + "shape": "IntegerEnum" + }, + "intEnum2": { + "shape": "IntegerEnum" + }, + "intEnum3": { + "shape": "IntegerEnum" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "intEnumSet": { + "shape": "IntegerEnumSet" + }, + "intEnumMap": { + "shape": "IntegerEnumMap" + } + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumSet": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "IntegerEnum" + } + }, + "String": { + "type": "string" + } }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": {}, - "body": "{ \"__type\": \"FooPrefix#ExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - } - ] - }, - { - "description": "Serialize document with standalone primitive type in a JSON response", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "inlineDocument": { - "shape": "DocumentType" + "cases": [ + { + "id": "AwsJson11IntEnums", + "given": { + "name": "JsonIntEnums", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonIntEnumsInputOutput" + }, + "documentation": "This example serializes intEnums as top level properties, in lists, sets, and maps.
", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "intEnum1": 1, + "intEnum2": 2, + "intEnum3": 3, + "intEnumList": [ + 1, + 2 + ], + "intEnumSet": [ + 1, + 2 + ], + "intEnumMap": { + "a": 1, + "b": 2 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonIntEnums" + }, + "body": "{\n \"intEnum1\": 1,\n \"intEnum2\": 2,\n \"intEnum3\": 3,\n \"intEnumList\": [\n 1,\n 2\n ],\n \"intEnumSet\": [\n 1,\n 2\n ],\n \"intEnumMap\": {\n \"a\": 1,\n \"b\": 2\n }\n}" + } } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "inlineDocument": "foo" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": \"foo\"}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "inlineDocument": 123 - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": 123}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "inlineDocument": 1.2 + { + "description": "Test cases for JsonUnions operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": 1.2}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "inlineDocument": true + "shapes": { + "UnionInputOutput": { + "type": "structure", + "members": { + "contents": { + "shape": "MyUnion" + } + }, + "documentation": "A shared structure that contains a single union member.
" + }, + "MyUnion": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "numberValue": { + "shape": "Integer" + }, + "blobValue": { + "shape": "Blob" + }, + "timestampValue": { + "shape": "Timestamp" + }, + "enumValue": { + "shape": "FooEnum" + }, + "listValue": { + "shape": "StringList" + }, + "mapValue": { + "shape": "StringMap" + }, + "structureValue": { + "shape": "GreetingStruct" + } + }, + "documentation": "A union with a representative set of types for members.
", + "union": true + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Blob": { + "type": "blob" + }, + "Timestamp": { + "type": "timestamp" + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": true}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + "cases": [ + { + "id": "AwsJson11DeserializeStringUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a string union value", + "result": { + "contents": { + "stringValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"stringValue\": \"foo\"\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeBooleanUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a boolean union value", + "result": { + "contents": { + "booleanValue": true + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"booleanValue\": true\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeNumberUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a number union value", + "result": { + "contents": { + "numberValue": 1 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"numberValue\": 1\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeBlobUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a blob union value", + "result": { + "contents": { + "blobValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"blobValue\": \"Zm9v\"\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeTimestampUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a timestamp union value", + "result": { + "contents": { + "timestampValue": 1398796238 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"timestampValue\": 1398796238\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes an enum union value", + "result": { + "contents": { + "enumValue": "Foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"enumValue\": \"Foo\"\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeListUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a list union value", + "result": { + "contents": { + "listValue": [ + "foo", + "bar" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"listValue\": [\"foo\", \"bar\"]\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeMapUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a map union value", + "result": { + "contents": { + "mapValue": { + "foo": "bar", + "spam": "eggs" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"mapValue\": {\n \"foo\": \"bar\",\n \"spam\": \"eggs\"\n }\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeStructureUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a structure union value", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + }, + { + "id": "AwsJson11DeserializeIgnoreType", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Ignores an unrecognized __type property", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"contents\": {\n \"__type\": \"aws.protocoltests.json10#MyUnion\",\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + } + ] + }, + { + "description": "Test cases for KitchenSinkOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "inlineDocument": "" + "shapes": { + "KitchenSink": { + "type": "structure", + "members": { + "Blob": { + "shape": "Blob" + }, + "Boolean": { + "shape": "Boolean" + }, + "Double": { + "shape": "Double" + }, + "EmptyStruct": { + "shape": "EmptyStruct" + }, + "Float": { + "shape": "Float" + }, + "HttpdateTimestamp": { + "shape": "SyntheticTimestamp_http_date" + }, + "Integer": { + "shape": "Integer" + }, + "Iso8601Timestamp": { + "shape": "SyntheticTimestamp_date_time" + }, + "JsonValue": { + "shape": "JsonValue", + "jsonvalue": true + }, + "ListOfLists": { + "shape": "ListOfListOfStrings" + }, + "ListOfMapsOfStrings": { + "shape": "ListOfMapsOfStrings" + }, + "ListOfStrings": { + "shape": "ListOfStrings" + }, + "ListOfStructs": { + "shape": "ListOfStructs" + }, + "Long": { + "shape": "Long" + }, + "MapOfListsOfStrings": { + "shape": "MapOfListsOfStrings" + }, + "MapOfMaps": { + "shape": "MapOfMapOfStrings" + }, + "MapOfStrings": { + "shape": "MapOfStrings" + }, + "MapOfStructs": { + "shape": "MapOfStructs" + }, + "RecursiveList": { + "shape": "ListOfKitchenSinks" + }, + "RecursiveMap": { + "shape": "MapOfKitchenSinks" + }, + "RecursiveStruct": { + "shape": "KitchenSink" + }, + "SimpleStruct": { + "shape": "SimpleStruct" + }, + "String": { + "shape": "String" + }, + "StructWithJsonName": { + "shape": "StructWithJsonName" + }, + "Timestamp": { + "shape": "Timestamp" + }, + "UnixTimestamp": { + "shape": "SyntheticTimestamp_epoch_seconds" + } + } + }, + "Blob": { + "type": "blob" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "EmptyStruct": { + "type": "structure", + "members": {} + }, + "Float": { + "type": "float", + "box": true + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "Integer": { + "type": "integer", + "box": true + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "JsonValue": { + "type": "string" + }, + "ListOfListOfStrings": { + "type": "list", + "member": { + "shape": "ListOfStrings" + } + }, + "ListOfMapsOfStrings": { + "type": "list", + "member": { + "shape": "MapOfStrings" + } + }, + "ListOfStrings": { + "type": "list", + "member": { + "shape": "String" + } + }, + "ListOfStructs": { + "type": "list", + "member": { + "shape": "SimpleStruct" + } + }, + "Long": { + "type": "long", + "box": true + }, + "MapOfListsOfStrings": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "ListOfStrings" + } + }, + "MapOfMapOfStrings": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "MapOfStrings" + } + }, + "MapOfStrings": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "MapOfStructs": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "SimpleStruct" + } + }, + "ListOfKitchenSinks": { + "type": "list", + "member": { + "shape": "KitchenSink" + } + }, + "MapOfKitchenSinks": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "KitchenSink" + } + }, + "SimpleStruct": { + "type": "structure", + "members": { + "Value": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + }, + "StructWithJsonName": { + "type": "structure", + "members": { + "Value": { + "shape": "String" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": \"\"}" - } - } - ] - }, - { - "description": "Serialize inline document in a JSON response", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "inlineDocument": { - "shape": "DocumentType" + "cases": [ + { + "id": "parses_operations_with_empty_json_bodies", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses operations with empty JSON bodies", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{}" + } + }, + { + "id": "parses_string_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses string shapes", + "result": { + "String": "string-value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"String\":\"string-value\"}" + } + }, + { + "id": "parses_integer_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses integer shapes", + "result": { + "Integer": 1234 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Integer\":1234}" + } + }, + { + "id": "parses_long_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses long shapes", + "result": { + "Long": 1234567890123456789 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Long\":1234567890123456789}" + } + }, + { + "id": "parses_float_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses float shapes", + "result": { + "Float": 1234.5 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Float\":1234.5}" + } + }, + { + "id": "parses_double_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses double shapes", + "result": { + "Double": 1.2345678912345679E8 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Double\":123456789.12345679}" + } + }, + { + "id": "parses_boolean_shapes_true", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses boolean shapes (true)", + "result": { + "Boolean": true + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Boolean\":true}" + } + }, + { + "id": "parses_boolean_false", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses boolean (false)", + "result": { + "Boolean": false + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Boolean\":false}" + } + }, + { + "id": "parses_blob_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses blob shapes", + "result": { + "Blob": "binary-value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Blob\":\"YmluYXJ5LXZhbHVl\"}" + } + }, + { + "id": "parses_timestamp_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses timestamp shapes", + "result": { + "Timestamp": 946845296 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Timestamp\":946845296}" + } + }, + { + "id": "parses_iso8601_timestamps", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses iso8601 timestamps", + "result": { + "Iso8601Timestamp": 946845296 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"Iso8601Timestamp\":\"2000-01-02T20:34:56Z\"}" + } + }, + { + "id": "parses_httpdate_timestamps", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses httpdate timestamps", + "result": { + "HttpdateTimestamp": 946845296 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"HttpdateTimestamp\":\"Sun, 02 Jan 2000 20:34:56 GMT\"}" + } + }, + { + "id": "parses_list_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses list shapes", + "result": { + "ListOfStrings": [ + "abc", + "mno", + "xyz" + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"ListOfStrings\":[\"abc\",\"mno\",\"xyz\"]}" + } + }, + { + "id": "parses_list_of_map_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses list of map shapes", + "result": { + "ListOfMapsOfStrings": [ + { + "size": "large" + }, + { + "color": "red" + } + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"ListOfMapsOfStrings\":[{\"size\":\"large\"},{\"color\":\"red\"}]}" + } + }, + { + "id": "parses_list_of_list_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses list of list shapes", + "result": { + "ListOfLists": [ + [ + "abc", + "mno", + "xyz" + ], + [ + "hjk", + "qrs", + "tuv" + ] + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"ListOfLists\":[[\"abc\",\"mno\",\"xyz\"],[\"hjk\",\"qrs\",\"tuv\"]]}" + } + }, + { + "id": "parses_list_of_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses list of structure shapes", + "result": { + "ListOfStructs": [ + { + "Value": "value-1" + }, + { + "Value": "value-2" + } + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"ListOfStructs\":[{\"Value\":\"value-1\"},{\"Value\":\"value-2\"}]}" + } + }, + { + "id": "parses_list_of_recursive_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses list of recursive structure shapes", + "result": { + "RecursiveList": [ + { + "RecursiveList": [ + { + "RecursiveList": [ + { + "String": "value" + } + ] + } + ] + } + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"RecursiveList\":[{\"RecursiveList\":[{\"RecursiveList\":[{\"String\":\"value\"}]}]}]}" + } + }, + { + "id": "parses_map_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses map shapes", + "result": { + "MapOfStrings": { + "size": "large", + "color": "red" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"MapOfStrings\":{\"size\":\"large\",\"color\":\"red\"}}" + } + }, + { + "id": "parses_map_of_list_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses map of list shapes", + "result": { + "MapOfListsOfStrings": { + "sizes": [ + "large", + "small" + ], + "colors": [ + "red", + "green" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"MapOfListsOfStrings\":{\"sizes\":[\"large\",\"small\"],\"colors\":[\"red\",\"green\"]}}" + } + }, + { + "id": "parses_map_of_map_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses map of map shapes", + "result": { + "MapOfMaps": { + "sizes": { + "large": "L", + "medium": "M" + }, + "colors": { + "red": "R", + "blue": "B" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"MapOfMaps\":{\"sizes\":{\"large\":\"L\",\"medium\":\"M\"},\"colors\":{\"red\":\"R\",\"blue\":\"B\"}}}" + } + }, + { + "id": "parses_map_of_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses map of structure shapes", + "result": { + "MapOfStructs": { + "size": { + "Value": "small" + }, + "color": { + "Value": "red" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"MapOfStructs\":{\"size\":{\"Value\":\"small\"},\"color\":{\"Value\":\"red\"}}}" + } + }, + { + "id": "parses_map_of_recursive_structure_shapes", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses map of recursive structure shapes", + "result": { + "RecursiveMap": { + "key-1": { + "RecursiveMap": { + "key-2": { + "RecursiveMap": { + "key-3": { + "String": "value" + } + } + } + } + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\"RecursiveMap\":{\"key-1\":{\"RecursiveMap\":{\"key-2\":{\"RecursiveMap\":{\"key-3\":{\"String\":\"value\"}}}}}}}" + } + }, + { + "id": "parses_the_request_id_from_the_response", + "given": { + "name": "KitchenSinkOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "KitchenSink" + } + }, + "description": "Parses the request id from the response", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1", + "X-Amzn-Requestid": "amazon-uniq-request-id" + }, + "body": "{}" + } } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + { + "description": "Test cases for NullOperation operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "inlineDocument": {"foo": "bar"} + "shapes": { + "NullOperationInputOutput": { + "type": "structure", + "members": { + "string": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"inlineDocument\": {\"foo\": \"bar\"}}" - } - } - ] - }, - { - "description": "Serialize aggregate documents in a JSON response", - "metadata": { - "protocol": "json" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "parentDocument": { - "shape": "DocumentType" + "cases": [ + { + "id": "AwsJson11StructuresDontDeserializeNullValues", + "given": { + "name": "NullOperation", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "NullOperationInputOutput" + } + }, + "description": "Null structure values are dropped", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"string\": null\n}" + } } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + { + "description": "Test cases for PutAndGetInlineDocuments operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "parentDocument": { - "str": "test", - "num": 123, - "float": 1.2, - "bool": true, - "null": "", - "document": {"foo": false}, - "list": ["myname", 321, 1.3, true, "", {"nested": true}, [200, ""]] - } + "shapes": { + "PutAndGetInlineDocumentsInputOutput": { + "type": "structure", + "members": { + "inlineDocument": { + "shape": "Document" + } + } + }, + "Document": { + "type": "structure", + "members": {}, + "document": true + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"parentDocument\": {\"str\": \"test\", \"num\": 123, \"float\": 1.2, \"bool\": true, \"null\": \"\", \"document\": {\"foo\": false}, \"list\": [\"myname\", 321, 1.3, true, \"\", {\"nested\": true}, [200, \"\"]]}}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" + "cases": [ + { + "id": "PutAndGetInlineDocumentsInput", + "given": { + "name": "PutAndGetInlineDocuments", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "PutAndGetInlineDocumentsInputOutput" + }, + "documentation": "This example serializes an inline document as part of the payload.
" + }, + "description": "Serializes inline documents in a JSON response.", + "result": { + "inlineDocument": { + "foo": "bar" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"inlineDocument\": {\"foo\": \"bar\"}\n}" + } + } + ] + }, + { + "description": "Test cases for SimpleScalarProperties operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2018-01-01", + "jsonVersion": "1.1", + "targetPrefix": "JsonProtocol" }, - "result": { - "parentDocument": [ - "test", - 123, - 1.2, - true, - "", - {"str": "myname", "num": 321, "float": 1.3, "bool": true, "null": "", "document": {"nested": true}, "list": [200, ""]}, - ["foo", false] - ] + "shapes": { + "SimpleScalarPropertiesInputOutput": { + "type": "structure", + "members": { + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double" + } + } + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"parentDocument\": [\"test\", 123, 1.2, true, \"\", {\"str\": \"myname\", \"num\": 321, \"float\": 1.3, \"bool\": true, \"null\": \"\", \"document\": {\"nested\": true}, \"list\": [200, \"\"]}, [\"foo\", false]]}" - } - } - ] - } + "cases": [ + { + "id": "AwsJson11SupportsNaNFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + } + }, + "description": "Supports handling NaN float values.", + "result": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"floatValue\": \"NaN\",\n \"doubleValue\": \"NaN\"\n}" + } + }, + { + "id": "AwsJson11SupportsInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + } + }, + "description": "Supports handling Infinity float values.", + "result": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"floatValue\": \"Infinity\",\n \"doubleValue\": \"Infinity\"\n}" + } + }, + { + "id": "AwsJson11SupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + } + }, + "description": "Supports handling -Infinity float values.", + "result": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.1" + }, + "body": "{\n \"floatValue\": \"-Infinity\",\n \"doubleValue\": \"-Infinity\"\n}" + } + } + ] + } ] diff --git a/tests/unit/protocols/output/json_1_0.json b/tests/unit/protocols/output/json_1_0.json new file mode 100644 index 0000000000..920a8bebae --- /dev/null +++ b/tests/unit/protocols/output/json_1_0.json @@ -0,0 +1,1157 @@ +[ + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "EmptyInputAndEmptyOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "AwsJson10EmptyInputAndEmptyOutputSendJsonObject", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "EmptyInputAndEmptyOutputOutput" + }, + "documentation": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has an empty input and empty output structure that reuses the same shape. While this should be rare, code generators must support this.
" + }, + "description": "A service will always return a JSON object for operations with modeled output.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{}" + } + } + ] + }, + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "InvalidGreeting": { + "type": "structure", + "members": { + "Message": { + "shape": "String" + } + }, + "documentation": "This error is thrown when an invalid greeting value is provided.
", + "exception": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "AwsJson10InvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "InvalidGreeting" + } + ] + }, + "description": "Parses simple JSON errors", + "errorCode": "InvalidGreeting", + "errorMessage": "Hi", + "error": { + "Message": "Hi" + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"aws.protocoltests.json10#InvalidGreeting\",\n \"Message\": \"Hi\"\n}" + } + } + ] + }, + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "FooError": { + "type": "structure", + "members": {}, + "documentation": "This error has test cases that test some of the dark corners of Amazon service framework history. It should only be implemented by clients.
", + "exception": true, + "fault": true + } + }, + "cases": [ + { + "id": "AwsJson10FooErrorUsingXAmznErrorType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Serializes the X-Amzn-ErrorType header. For an example service, see Amazon EKS.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "FooError" + } + } + }, + { + "id": "AwsJson10FooErrorUsingXAmznErrorTypeWithUri", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some X-Amzn-Errortype headers contain URLs. Clients need to split the URL on ':' and take only the first half of the string. For example, 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/'\nis to be interpreted as 'ValidationException'.\n\nFor an example service see Amazon Polly.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "AwsJson10FooErrorUsingXAmznErrorTypeWithUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "X-Amzn-Errortype might contain a URL and a namespace. Client should extract only the shape name. This is a pathalogical case that might not actually happen in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "AwsJson10FooErrorUsingCode", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "This example uses the 'code' property in the output rather than X-Amzn-Errortype. Some services do this though it's preferable to send the X-Amzn-Errortype. Client implementations must first check for the X-Amzn-Errortype and then check for a top-level 'code' property.\n\nFor example service see Amazon S3 Glacier.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"code\": \"FooError\"\n}" + } + }, + { + "id": "AwsJson10FooErrorUsingCodeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"code\": \"aws.protocoltests.json10#FooError\"\n}" + } + }, + { + "id": "AwsJson10FooErrorUsingCodeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"code\": \"aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + }, + { + "id": "AwsJson10FooErrorWithDunderType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"FooError\"\n}" + } + }, + { + "id": "AwsJson10FooErrorWithDunderTypeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"aws.protocoltests.json10#FooError\"\n}" + } + }, + { + "id": "AwsJson10FooErrorWithDunderTypeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + } + ] + }, + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "ComplexError": { + "type": "structure", + "members": { + "TopLevel": { + "shape": "String" + }, + "Nested": { + "shape": "ComplexNestedErrorData" + } + }, + "documentation": "This error is thrown when a request is invalid.
", + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "AwsJson10ComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "description": "Parses a complex error with no message member", + "errorCode": "ComplexError", + "error": { + "TopLevel": "Top level", + "Nested": { + "Foo": "bar" + } + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"aws.protocoltests.json10#ComplexError\",\n \"TopLevel\": \"Top level\",\n \"Nested\": {\n \"Foo\": \"bar\"\n }\n}" + } + }, + { + "id": "AwsJson10EmptyComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly deserialize successful and error responses.
", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "description": "Parses a complex error with an empty body", + "errorCode": "ComplexError", + "error": {}, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"__type\": \"aws.protocoltests.json10#ComplexError\"\n}" + } + } + ] + }, + { + "description": "Test cases for JsonUnions operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "JsonUnionsOutput": { + "type": "structure", + "members": { + "contents": { + "shape": "MyUnion" + } + } + }, + "MyUnion": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "numberValue": { + "shape": "Integer" + }, + "blobValue": { + "shape": "Blob" + }, + "timestampValue": { + "shape": "Timestamp" + }, + "enumValue": { + "shape": "FooEnum" + }, + "intEnumValue": { + "shape": "IntegerEnum" + }, + "listValue": { + "shape": "StringList" + }, + "mapValue": { + "shape": "StringMap" + }, + "structureValue": { + "shape": "GreetingStruct" + } + }, + "documentation": "A union with a representative set of types for members.
", + "union": true + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Blob": { + "type": "blob" + }, + "Timestamp": { + "type": "timestamp" + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "AwsJson10DeserializeStringUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a string union value", + "result": { + "contents": { + "stringValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"stringValue\": \"foo\"\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeBooleanUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a boolean union value", + "result": { + "contents": { + "booleanValue": true + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"booleanValue\": true\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeNumberUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a number union value", + "result": { + "contents": { + "numberValue": 1 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"numberValue\": 1\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeBlobUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a blob union value", + "result": { + "contents": { + "blobValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"blobValue\": \"Zm9v\"\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeTimestampUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a timestamp union value", + "result": { + "contents": { + "timestampValue": 1398796238 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"timestampValue\": 1398796238\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes an enum union value", + "result": { + "contents": { + "enumValue": "Foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"enumValue\": \"Foo\"\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeIntEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes an intEnum union value", + "result": { + "contents": { + "intEnumValue": 1 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"intEnumValue\": 1\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeListUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a list union value", + "result": { + "contents": { + "listValue": [ + "foo", + "bar" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"listValue\": [\"foo\", \"bar\"]\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeMapUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a map union value", + "result": { + "contents": { + "mapValue": { + "foo": "bar", + "spam": "eggs" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"mapValue\": {\n \"foo\": \"bar\",\n \"spam\": \"eggs\"\n }\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeStructureUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a structure union value", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeIgnoreType", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Ignores an unrecognized __type property", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"__type\": \"aws.protocoltests.json10#MyUnion\",\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + }, + { + "id": "AwsJson10DeserializeAllowNulls", + "given": { + "name": "JsonUnions", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "JsonUnionsOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Allows for `: null` to be set for all unset fields", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"contents\": {\n \"stringValue\": null,\n \"booleanValue\": null,\n \"numberValue\": null,\n \"blobValue\": null,\n \"timestampValue\": null,\n \"enumValue\": null,\n \"intEnumValue\": null,\n \"listValue\": null,\n \"mapValue\": null,\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + } + ] + }, + { + "description": "Test cases for NoInputAndNoOutput operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": {}, + "cases": [ + { + "id": "AwsJson10HandlesEmptyOutputShape", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.
" + }, + "description": "When no output is defined, the service is expected to return\nan empty payload, however, client must ignore a JSON payload\nif one is returned. This ensures that if output is added later,\nthen it will not break the client.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{}" + } + }, + { + "id": "AwsJson10HandlesUnexpectedJsonOutput", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.
" + }, + "description": "This client-only test builds on handles_empty_output_shape,\nby including unexpected fields in the JSON. A client\nneeds to ignore JSON output that is empty or that contains\nJSON object data.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"foo\": true\n}" + } + }, + { + "id": "AwsJson10ServiceRespondsWithNoPayload", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.
" + }, + "description": "When no output is defined, the service is expected to return\nan empty payload. Despite the lack of a payload, the service\nis expected to always send a Content-Type header. Clients must\nhandle cases where a service returns a JSON object and where\na service returns no JSON at all.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "" + } + } + ] + }, + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "NoInputAndOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "AwsJson10NoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "NoInputAndOutputOutput" + }, + "documentation": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input and the output is empty. While this should be rare, code generators must support this.
" + }, + "description": "Empty output always serializes an empty object payload.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{}" + } + } + ] + }, + { + "description": "Test cases for SimpleScalarProperties operation", + "metadata": { + "protocol": "json", + "protocols": [ + "json" + ], + "apiVersion": "2020-07-14", + "jsonVersion": "1.0", + "targetPrefix": "JsonRpc10" + }, + "shapes": { + "SimpleScalarPropertiesOutput": { + "type": "structure", + "members": { + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double" + } + } + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "AwsJson10SupportsNaNFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesOutput" + } + }, + "description": "Supports handling NaN float values.", + "result": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"floatValue\": \"NaN\",\n \"doubleValue\": \"NaN\"\n}" + } + }, + { + "id": "AwsJson10SupportsInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesOutput" + } + }, + "description": "Supports handling Infinity float values.", + "result": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"floatValue\": \"Infinity\",\n \"doubleValue\": \"Infinity\"\n}" + } + }, + { + "id": "AwsJson10SupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "SimpleScalarPropertiesOutput" + } + }, + "description": "Supports handling -Infinity float values.", + "result": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/x-amz-json-1.0" + }, + "body": "{\n \"floatValue\": \"-Infinity\",\n \"doubleValue\": \"-Infinity\"\n}" + } + } + ] + } +] diff --git a/tests/unit/protocols/output/query.json b/tests/unit/protocols/output/query.json index 3faf5eb041..8195a44957 100644 --- a/tests/unit/protocols/output/query.json +++ b/tests/unit/protocols/output/query.json @@ -1,931 +1,2375 @@ [ - { - "description": "Scalar members", - "metadata": { - "protocol": "query" - }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Str": { - "shape": "StringType" - }, - "Num": { - "shape": "IntegerType", - "locationName": "FooNum" - }, - "FalseBool": { - "shape": "BooleanType" - }, - "TrueBool": { - "shape": "BooleanType" - }, - "Float": { - "shape": "FloatType" - }, - "Double": { - "shape": "DoubleType" - }, - "Long": { - "shape": "LongType" - }, - "Char": { - "shape": "CharType" - }, - "Timestamp": { - "shape": "TimestampType" - } - } - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - }, - "BooleanType": { - "type": "boolean" - }, - "FloatType": { - "type": "float" - }, - "DoubleType": { - "type": "double" - }, - "LongType": { - "type": "long" - }, - "CharType": { - "type": "character" - }, - "TimestampType": { - "type": "timestamp" - } - }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Str": "myname", - "Num": 123, - "FalseBool": false, - "TrueBool": true, - "Float": 1.2, - "Double": 1.3, - "Long": 200, - "Char": "a", - "Timestamp": 1422172800 - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "The example tests how requests and responses are serialized when there's no request or response members.
While this should be rare, code generators must support this.
" + }, + "description": "Empty output", + "result": {}, + "response": { + "status_code": 200 + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "flattened": true, - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for FlattenedXmlMap operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "FlattenedXmlMapOutput": { + "type": "structure", + "members": { + "myMap": { + "shape": "FooEnumMap", + "flattened": true + } + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryQueryFlattenedXmlMap", + "given": { + "name": "FlattenedXmlMap", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "FlattenedXmlMapOutput" + }, + "documentation": "Flattened maps
" + }, + "description": "Serializes flattened XML maps in responses", + "result": { + "myMap": { + "foo": "Foo", + "baz": "Baz" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "Flattened maps with @xmlName
" + }, + "description": "Serializes flattened XML maps in responses that have xmlName on members", + "result": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "Flattened maps with @xmlNamespace and @xmlName
" + }, + "description": "Serializes flattened XML maps in responses that have xmlNamespace and xmlName on members", + "result": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "This operation has three possible return values:
This error is thrown when an invalid greeting value is provided.
", + "exception": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "QueryInvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
InvalidGreeting
\n This operation has three possible return values:
Customized
\n This error is thrown when a request is invalid.
", + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "QueryComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "POST", + "requestUri": "/" + }, + "documentation": "This operation has three possible return values:
ComplexError
\n The xmlName trait on the output structure is ignored in AWS Query.
The wrapping element is always operation name + "Response", and inside of that wrapper is another wrapper named operation name + "Result".
" + }, + "description": "The xmlName trait on the output structure is ignored in AWS Query", + "result": { + "foo": "bar" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output.
While this should be rare, code generators must support this.
" + }, + "description": "Empty output. Note that no assertion is made on the output body itself.", + "result": {}, + "response": { + "status_code": 200 + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "StringMap" - } - } - }, - "StringMap": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StructType" - } - }, - "StringType": { - "type": "string" - }, - "StructType": { - "type": "structure", - "members": { - "foo": { - "shape": "StringType" - } - } - } + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "query", + "protocols": [ + "query" + ], + "apiVersion": "2020-01-08" + }, + "shapes": { + "NoInputAndOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "QueryNoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "NoInputAndOutputOutput" + }, + "documentation": "The example tests how requests and responses are serialized when there's no request payload or response members.
While this should be rare, code generators must support this.
" + }, + "description": "Empty output", + "result": {}, + "response": { + "status_code": 200 + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "resultWrapper": "OperationNameResult", - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": { - "foo": "bar" - }, - "baz": { - "foo": "bam" - } - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "Recursive shapes
" + }, + "description": "Serializes recursive structures", + "result": { + "nested": { + "foo": "Foo1", + "nested": { + "bar": "Bar1", + "recursiveMember": { + "foo": "Foo2", + "nested": { + "bar": "Bar2" + } + } + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "Blobs are base64 encoded
" + }, + "description": "Blobs are base64 encoded", + "result": { + "data": "value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "A list of lists of strings.
" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "QueryXmlEmptyLists", + "given": { + "name": "XmlEmptyLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlListsOutput" + } + }, + "description": "Deserializes empty XML lists", + "result": { + "stringList": [], + "stringSet": [] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "This example serializes enums as top level properties, in lists, sets, and maps.
" + }, + "description": "Serializes simple scalar properties", + "result": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "This example serializes enums as top level properties, in lists, sets, and maps.
" + }, + "description": "Serializes simple scalar properties", + "result": { + "intEnum1": 1, + "intEnum2": 2, + "intEnum3": 3, + "intEnumList": [ + 1, + 2 + ], + "intEnumSet": [ + 1, + 2 + ], + "intEnumMap": { + "a": 1, + "b": 2 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "A list of lists of strings.
" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "QueryXmlLists", + "given": { + "name": "XmlLists", + "http": { + "method": "POST", + "requestUri": "/" + }, + "output": { + "shape": "XmlListsOutput" + }, + "documentation": "This test case serializes XML lists for the following cases for both input and output:
The example tests basic map serialization.
" + }, + "description": "Tests for XML map serialization", + "result": { + "myMap": { + "foo": { + "hi": "there" + }, + "baz": { + "hi": "bye" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "ExceptionShape
OtherExceptionShape
UndefinedShape
This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Tests how normal timestamps are serialized", + "result": { + "normal": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of date-time works like normal timestamps", + "result": { + "dateTime": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "result": { + "dateTimeOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of epoch-seconds works", + "result": { + "epochSeconds": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "result": { + "epochSecondsOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of http-date works", + "result": { + "httpDate": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of http-date on the target shape works", + "result": { + "httpDateOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/xml" + }, + "body": "This example serializes a document as part of the payload.
", + "idempotent": true + }, + "description": "Serializes documents as part of the JSON response payload with no escaping.", + "result": { + "stringValue": "string", + "documentValue": { + "foo": "bar" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": {\n \"foo\": \"bar\"\n }\n}" + } + }, + { + "id": "DocumentOutputString", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "This example serializes a document as part of the payload.
", + "idempotent": true + }, + "description": "Document types can be JSON scalars too.", + "result": { + "stringValue": "string", + "documentValue": "hello" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": \"hello\"\n}" + } + }, + { + "id": "DocumentOutputNumber", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "This example serializes a document as part of the payload.
", + "idempotent": true + }, + "description": "Document types can be JSON scalars too.", + "result": { + "stringValue": "string", + "documentValue": 10 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": 10\n}" + } + }, + { + "id": "DocumentOutputBoolean", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "This example serializes a document as part of the payload.
", + "idempotent": true + }, + "description": "Document types can be JSON scalars too.", + "result": { + "stringValue": "string", + "documentValue": false + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": false\n}" + } + }, + { + "id": "DocumentOutputArray", + "given": { + "name": "DocumentType", + "http": { + "method": "PUT", + "requestUri": "/DocumentType", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeInputOutput" + }, + "documentation": "This example serializes a document as part of the payload.
", + "idempotent": true + }, + "description": "Document types can be JSON arrays.", + "result": { + "stringValue": "string", + "documentValue": [ + true, + false + ] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": \"string\",\n \"documentValue\": [\n true,\n false\n ]\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for DocumentTypeAsMapValue operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "DocumentTypeAsMapValueInputOutput": { + "type": "structure", + "members": { + "docValuedMap": { + "shape": "DocumentValuedMap" + } + } + }, + "DocumentValuedMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "Document" + } + }, + "Document": { + "type": "structure", + "members": {}, + "document": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "DocumentTypeAsMapValueOutput", + "given": { + "name": "DocumentTypeAsMapValue", + "http": { + "method": "PUT", + "requestUri": "/DocumentTypeAsMapValue", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeAsMapValueInputOutput" + }, + "documentation": "This example serializes documents as the value of maps.
", + "idempotent": true + }, + "description": "Serializes a map that uses documents as the value.", + "result": { + "docValuedMap": { + "foo": { + "f": 1, + "o": 2 + }, + "bar": [ + "b", + "a", + "r" + ], + "baz": "BAZ" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"docValuedMap\": {\n \"foo\": { \"f\": 1, \"o\": 2 },\n \"bar\": [ \"b\", \"a\", \"r\" ],\n \"baz\": \"BAZ\"\n }\n}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["a", "b"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"ListMember\": [\"a\", \"b\"]}" - } - } - ] - }, - { - "description": "Lists with structure member", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for DocumentTypeAsPayload operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "DocumentTypeAsPayloadInputOutput": { + "type": "structure", + "members": { + "documentValue": { + "shape": "Document" + } + }, + "payload": "documentValue" + }, + "Document": { + "type": "structure", + "members": {}, + "document": true + } + }, + "cases": [ + { + "id": "DocumentTypeAsPayloadOutput", + "given": { + "name": "DocumentTypeAsPayload", + "http": { + "method": "PUT", + "requestUri": "/DocumentTypeAsPayload", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeAsPayloadInputOutput" + }, + "documentation": "This example serializes a document as the entire HTTP payload.
", + "idempotent": true + }, + "description": "Serializes a document as the target of the httpPayload trait.", + "result": { + "documentValue": { + "foo": "bar" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"foo\": \"bar\"\n}" + } + }, + { + "id": "DocumentTypeAsPayloadOutputString", + "given": { + "name": "DocumentTypeAsPayload", + "http": { + "method": "PUT", + "requestUri": "/DocumentTypeAsPayload", + "responseCode": 200 + }, + "output": { + "shape": "DocumentTypeAsPayloadInputOutput" + }, + "documentation": "This example serializes a document as the entire HTTP payload.
", + "idempotent": true + }, + "description": "Serializes a document as a payload string.", + "result": { + "documentValue": "hello" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "\"hello\"" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListType" - } - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "SingleStruct" - } - }, - "StringType": { - "type": "string" - }, - "SingleStruct": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - } - } - } + { + "description": "Test cases for EmptyInputAndEmptyOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "EmptyInputAndEmptyOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "RestJsonEmptyInputAndEmptyOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/EmptyInputAndEmptyOutput", + "responseCode": 200 + }, + "output": { + "shape": "EmptyInputAndEmptyOutputOutput" + }, + "documentation": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has an empty input and empty output structure that reuses the same shape. While this should be rare, code generators must support this.
" + }, + "description": "As of January 2021, server implementations are expected to\nrespond with a JSON object regardless of if the output\nparameters are empty.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{}" + } + }, + { + "id": "RestJsonEmptyInputAndEmptyOutputJsonObjectOutput", + "given": { + "name": "EmptyInputAndEmptyOutput", + "http": { + "method": "POST", + "requestUri": "/EmptyInputAndEmptyOutput", + "responseCode": 200 + }, + "output": { + "shape": "EmptyInputAndEmptyOutputOutput" + }, + "documentation": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has an empty input and empty output structure that reuses the same shape. While this should be rare, code generators must support this.
" + }, + "description": "This test ensures that clients can gracefully handle\nsituations where a service omits a JSON payload entirely.", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": [{"Foo": "a"}, {"Foo": "b"}] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"ListMember\": [{\"Foo\": \"a\"}, {\"Foo\": \"b\"}]}" - } - } - ] - }, - { - "description": "Maps", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for FractionalSeconds operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "FractionalSecondsOutput": { + "type": "structure", + "members": { + "datetime": { + "shape": "DateTime" + } + } + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "RestJsonDateTimeWithFractionalSeconds", + "given": { + "name": "FractionalSeconds", + "http": { + "method": "POST", + "requestUri": "/FractionalSeconds", + "responseCode": 200 + }, + "output": { + "shape": "FractionalSecondsOutput" + } + }, + "description": "Ensures that clients can correctly parse datetime timestamps with fractional seconds", + "result": { + "datetime": 9.46845296123E8 + }, + "response": { + "status_code": 200, + "body": " {\n \"datetime\": \"2000-01-02T20:34:56.123Z\"\n }\n" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "MapMember": { - "shape": "MapType" - } - } - }, - "MapType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "ListType" - } - }, - "ListType": { - "type": "list", - "member": { - "shape": "IntegerType" - } - }, - "StringType": { - "type": "string" - }, - "IntegerType": { - "type": "integer" - } + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "GreetingWithErrorsOutput": { + "type": "structure", + "members": { + "greeting": { + "shape": "String", + "location": "header", + "locationName": "X-Greeting" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonGreetingWithErrors", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "output": { + "shape": "GreetingWithErrorsOutput" + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true + }, + "description": "Ensures that operations with errors successfully know how\nto deserialize a successful response. As of January 2021,\nserver implementations are expected to respond with a\nJSON object regardless of if the output parameters are\nempty.", + "result": { + "greeting": "Hello" + }, + "response": { + "status_code": 200, + "headers": { + "X-Greeting": "Hello" + }, + "body": "{}" + } + }, + { + "id": "RestJsonGreetingWithErrorsNoPayload", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "output": { + "shape": "GreetingWithErrorsOutput" + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true + }, + "description": "This test is similar to RestJsonGreetingWithErrors, but it\nensures that clients can gracefully deal with a server\nomitting a response payload.", + "result": { + "greeting": "Hello" + }, + "response": { + "status_code": 200, + "headers": { + "X-Greeting": "Hello" + }, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "MapMember": { - "a": [1, 2], - "b": [3, 4] - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"MapMember\": {\"a\": [1, 2], \"b\": [3, 4]}}" - } - } - ] - }, - { - "description": "Complex Map Values", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "FooError": { + "type": "structure", + "members": {}, + "documentation": "This error has test cases that test some of the dark corners of Amazon service framework history. It should only be implemented by clients.
", + "error": { + "httpStatusCode": 500 + }, + "exception": true, + "fault": true + } + }, + "cases": [ + { + "id": "RestJsonFooErrorUsingXAmznErrorType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Serializes the X-Amzn-ErrorType header. For an example service, see Amazon EKS.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "FooError" + } + } + }, + { + "id": "RestJsonFooErrorUsingXAmznErrorTypeWithUri", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some X-Amzn-Errortype headers contain URLs. Clients need to split the URL on ':' and take only the first half of the string. For example, 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/'\nis to be interpreted as 'ValidationException'.\n\nFor an example service see Amazon Polly.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "RestJsonFooErrorUsingXAmznErrorTypeWithUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "X-Amzn-Errortype might contain a URL and a namespace. Client should extract only the shape name. This is a pathalogical case that might not actually happen in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "X-Amzn-Errortype": "aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + } + }, + { + "id": "RestJsonFooErrorUsingCode", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "This example uses the 'code' property in the output rather than X-Amzn-Errortype. Some services do this though it's preferable to send the X-Amzn-Errortype. Client implementations must first check for the X-Amzn-Errortype and then check for a top-level 'code' property.\n\nFor example service see Amazon S3 Glacier.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"code\": \"FooError\"\n}" + } + }, + { + "id": "RestJsonFooErrorUsingCodeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"code\": \"aws.protocoltests.restjson#FooError\"\n}" + } + }, + { + "id": "RestJsonFooErrorUsingCodeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using code, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"code\": \"aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + }, + { + "id": "RestJsonFooErrorWithDunderType", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"__type\": \"FooError\"\n}" + } + }, + { + "id": "RestJsonFooErrorWithDunderTypeAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"__type\": \"aws.protocoltests.restjson#FooError\"\n}" + } + }, + { + "id": "RestJsonFooErrorWithDunderTypeUriAndNamespace", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "FooError" + } + ] + }, + "description": "Some services serialize errors using __type, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "errorCode": "FooError", + "error": {}, + "response": { + "status_code": 500, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"__type\": \"aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/\"\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "MapMember": { - "shape": "MapType" - } - } - }, - "MapType": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "TimeType" - } - }, - "TimeType": { - "type": "timestamp" - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "ComplexError": { + "type": "structure", + "members": { + "Header": { + "shape": "String", + "location": "header", + "locationName": "X-Header" + }, + "TopLevel": { + "shape": "String" + }, + "Nested": { + "shape": "ComplexNestedErrorData" + } + }, + "documentation": "This error is thrown when a request is invalid.
", + "error": { + "httpStatusCode": 403, + "senderFault": true + }, + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String", + "locationName": "Fooooo" + } + } + } + }, + "cases": [ + { + "id": "RestJsonComplexErrorWithNoMessage", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "description": "Serializes a complex error with no message member", + "errorCode": "ComplexError", + "error": { + "Header": "Header", + "TopLevel": "Top level", + "Nested": { + "Foo": "bar" + } + }, + "response": { + "status_code": 403, + "headers": { + "Content-Type": "application/json", + "X-Amzn-Errortype": "ComplexError", + "X-Header": "Header" + }, + "body": "{\n \"TopLevel\": \"Top level\",\n \"Nested\": {\n \"Fooooo\": \"bar\"\n }\n}" + } + }, + { + "id": "RestJsonEmptyComplexErrorWithNoMessage", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "errorCode": "ComplexError", + "error": {}, + "response": { + "status_code": 403, + "headers": { + "Content-Type": "application/json", + "X-Amzn-Errortype": "ComplexError" + }, + "body": "{}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "MapMember": { - "a": 1398796238, - "b": 1398796238 - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"MapMember\": {\"a\": 1398796238, \"b\": 1398796238}}" - } - } - ] - }, - { - "description": "Ignores extra data", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "InvalidGreeting": { + "type": "structure", + "members": { + "Message": { + "shape": "String" + } + }, + "documentation": "This error is thrown when an invalid greeting value is provided.
", + "error": { + "httpStatusCode": 400, + "senderFault": true + }, + "exception": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonInvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has four possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "InvalidGreeting" + } + ] + }, + "description": "Parses simple JSON errors", + "errorCode": "InvalidGreeting", + "errorMessage": "Hi", + "error": { + "Message": "Hi" + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/json", + "X-Amzn-Errortype": "InvalidGreeting" + }, + "body": "{\n \"Message\": \"Hi\"\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "StrType": { - "shape": "StrType" - } - } - }, - "StrType": { - "type": "string" - } + { + "description": "Test cases for HttpEnumPayload operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "EnumPayloadInput": { + "type": "structure", + "members": { + "payload": { + "shape": "StringEnum" + } + }, + "payload": "payload" + }, + "StringEnum": { + "type": "string", + "enum": [ + "enumvalue" + ] + } + }, + "cases": [ + { + "id": "RestJsonEnumPayloadResponse", + "given": { + "name": "HttpEnumPayload", + "http": { + "method": "POST", + "requestUri": "/EnumPayload", + "responseCode": 200 + }, + "output": { + "shape": "EnumPayloadInput" + } + }, + "result": { + "payload": "enumvalue" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/plain" + }, + "body": "enumvalue" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": {}, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"foo\": \"bar\"}" - } - } - ] - }, - { - "description": "Ignores undefined output", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for HttpPayloadTraits operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadTraitsInputOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "blob": { + "shape": "Blob" + } + }, + "payload": "blob" + }, + "String": { + "type": "string" + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "RestJsonHttpPayloadTraitsWithBlob", + "given": { + "name": "HttpPayloadTraits", + "http": { + "method": "POST", + "requestUri": "/HttpPayloadTraits", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadTraitsInputOutput" + }, + "documentation": "This example serializes a blob shape in the payload.
In this example, no JSON document is synthesized because the payload is not a structure or a union type.
" + }, + "description": "Serializes a blob in the HTTP payload", + "result": { + "foo": "Foo", + "blob": "blobby blob blob" + }, + "response": { + "status_code": 200, + "headers": { + "X-Foo": "Foo" + }, + "body": "blobby blob blob" + } + }, + { + "id": "RestJsonHttpPayloadTraitsWithNoBlobBody", + "given": { + "name": "HttpPayloadTraits", + "http": { + "method": "POST", + "requestUri": "/HttpPayloadTraits", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadTraitsInputOutput" + }, + "documentation": "This example serializes a blob shape in the payload.
In this example, no JSON document is synthesized because the payload is not a structure or a union type.
" + }, + "description": "Serializes an empty blob in the HTTP payload", + "result": { + "foo": "Foo" + }, + "response": { + "status_code": 200, + "headers": { + "X-Foo": "Foo" + }, + "body": "" + } + } + ] }, - "shapes": {}, - "cases": [ - { - "given": { - "name": "OperationName" - }, - "result": {}, - "response": { - "status_code": 200, - "headers": {}, - "body": "OK" - } - } - ] - }, - { - "description": "Supports header maps", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for HttpPayloadWithStructure operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithStructureInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "NestedPayload" + } + }, + "payload": "nested" + }, + "NestedPayload": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + }, + "name": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonHttpPayloadWithStructure", + "given": { + "name": "HttpPayloadWithStructure", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithStructure", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithStructureInputOutput" + }, + "documentation": "This example serializes a structure in the payload.
Note that serializing a structure changes the wrapper element name to match the targeted structure.
", + "idempotent": true + }, + "description": "Serializes a structure in the payload", + "result": { + "nested": { + "greeting": "hello", + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"greeting\": \"hello\",\n \"name\": \"Phreddy\"\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "AllHeaders": { - "shape": "HeaderMap", - "location": "headers" - }, - "PrefixedHeaders": { - "shape": "HeaderMap", - "location": "headers", - "locationName": "X-" - } - } - }, - "HeaderMap": { - "type": "map", - "key": { - "shape": "StringType" - }, - "value": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for HttpPayloadWithUnion operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithUnionInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "UnionPayload" + } + }, + "payload": "nested" + }, + "UnionPayload": { + "type": "structure", + "members": { + "greeting": { + "shape": "String" + } + }, + "union": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonHttpPayloadWithUnion", + "given": { + "name": "HttpPayloadWithUnion", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithUnion", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithUnionInputOutput" + }, + "documentation": "This example serializes a union in the payload.
", + "idempotent": true + }, + "description": "Serializes a union in the payload.", + "result": { + "nested": { + "greeting": "hello" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"greeting\": \"hello\"\n}" + } + }, + { + "id": "RestJsonHttpPayloadWithUnsetUnion", + "given": { + "name": "HttpPayloadWithUnion", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithUnion", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithUnionInputOutput" + }, + "documentation": "This example serializes a union in the payload.
", + "idempotent": true + }, + "description": "No payload is sent if the union has no value.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Length": "0" + }, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "AllHeaders": { - "Content-Length": "10", - "x-Foo": "bar", - "X-bam": "boo" - }, - "PrefixedHeaders": { - "Foo": "bar", - "bam": "boo" - } - }, - "response": { - "status_code": 200, - "headers": { - "Content-Length": "10", - "x-Foo": "bar", - "X-bam": "boo" - }, - "body": "{}" - } - } - ] - }, - { - "description": "JSON payload", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for HttpPrefixHeaders operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPrefixHeadersOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "x-foo" + }, + "fooMap": { + "shape": "StringMap", + "location": "headers", + "locationName": "x-foo-" + } + } + }, + "String": { + "type": "string" + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + } + }, + "cases": [ + { + "id": "RestJsonHttpPrefixHeadersArePresent", + "given": { + "name": "HttpPrefixHeaders", + "http": { + "method": "GET", + "requestUri": "/HttpPrefixHeaders", + "responseCode": 200 + }, + "output": { + "shape": "HttpPrefixHeadersOutput" + }, + "documentation": "This examples adds headers to the input of a request and response by prefix.
" + }, + "description": "Adds headers by prefix", + "result": { + "foo": "Foo", + "fooMap": { + "abc": "Abc value", + "def": "Def value" + } + }, + "response": { + "status_code": 200, + "headers": { + "x-foo": "Foo", + "x-foo-abc": "Abc value", + "x-foo-def": "Def value" + } + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "payload": "Data", - "members": { - "Header": { - "shape": "StringType", - "location": "header", - "locationName": "X-Foo" - }, - "Data": { - "shape": "BodyStructure" - } - } - }, - "BodyStructure": { - "type": "structure", - "members": { - "Foo": { - "shape": "StringType" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for HttpPrefixHeadersInResponse operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPrefixHeadersInResponseOutput": { + "type": "structure", + "members": { + "prefixHeaders": { + "shape": "StringMap", + "location": "headers", + "locationName": "" + } + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPrefixHeadersResponse", + "given": { + "name": "HttpPrefixHeadersInResponse", + "http": { + "method": "GET", + "requestUri": "/HttpPrefixHeadersResponse", + "responseCode": 200 + }, + "output": { + "shape": "HttpPrefixHeadersInResponseOutput" + }, + "documentation": "Clients that perform this test extract all headers from the response.
" + }, + "description": "(de)serializes all response headers", + "result": { + "prefixHeaders": { + "x-foo": "Foo", + "hello": "Hello" + } + }, + "response": { + "status_code": 200, + "headers": { + "hello": "Hello", + "x-foo": "Foo" + } + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Header": "baz", - "Data": { - "Foo": "abc" - } - }, - "response": { - "status_code": 200, - "headers": { - "X-Foo": "baz" - }, - "body": "{\"Foo\": \"abc\"}" - } - } - ] - }, - { - "description": "Streaming payload", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for HttpResponseCode operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpResponseCodeOutput": { + "type": "structure", + "members": { + "Status": { + "shape": "Integer", + "location": "statusCode" + } + } + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "RestJsonHttpResponseCode", + "given": { + "name": "HttpResponseCode", + "http": { + "method": "PUT", + "requestUri": "/HttpResponseCode", + "responseCode": 200 + }, + "output": { + "shape": "HttpResponseCodeOutput" + }, + "idempotent": true + }, + "description": "Binds the http response code to an output structure. Note that\neven though all members are bound outside of the payload, an\nempty JSON object is serialized in the response. However,\nclients should be able to handle an empty JSON object or an\nempty payload without failing to deserialize a response.", + "result": { + "Status": 201 + }, + "response": { + "status_code": 201, + "headers": { + "Content-Type": "application/json" + }, + "body": "{}" + } + }, + { + "id": "RestJsonHttpResponseCodeWithNoPayload", + "given": { + "name": "HttpResponseCode", + "http": { + "method": "PUT", + "requestUri": "/HttpResponseCode", + "responseCode": 200 + }, + "output": { + "shape": "HttpResponseCodeOutput" + }, + "idempotent": true + }, + "description": "This test ensures that clients gracefully handle cases where\nthe service responds with no payload rather than an empty JSON\nobject.", + "result": { + "Status": 201 + }, + "response": { + "status_code": 201, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "payload": "Stream", - "members": { - "Stream": { - "shape": "Stream" - } - } - }, - "Stream": { - "type": "blob" - } + { + "description": "Test cases for HttpStringPayload operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "StringPayloadInput": { + "type": "structure", + "members": { + "payload": { + "shape": "String" + } + }, + "payload": "payload" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonStringPayloadResponse", + "given": { + "name": "HttpStringPayload", + "http": { + "method": "POST", + "requestUri": "/StringPayload", + "responseCode": 200 + }, + "output": { + "shape": "StringPayloadInput" + } + }, + "result": { + "payload": "rawstring" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "text/plain" + }, + "body": "rawstring" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Stream": "abc" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "abc" - } - } - ] - }, - { - "description": "JSON value trait", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for IgnoreQueryParamsInResponse operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "IgnoreQueryParamsInResponseOutput": { + "type": "structure", + "members": { + "baz": { + "shape": "String", + "location": "uri", + "locationName": "baz" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonIgnoreQueryParamsInResponse", + "given": { + "name": "IgnoreQueryParamsInResponse", + "http": { + "method": "GET", + "requestUri": "/IgnoreQueryParamsInResponse", + "responseCode": 200 + }, + "output": { + "shape": "IgnoreQueryParamsInResponseOutput" + }, + "documentation": "This example ensures that query string bound request parameters are serialized in the body of responses if the structure is used in both the request and response.
" + }, + "description": "Query parameters must be ignored when serializing the output\nof an operation. As of January 2021, server implementations\nare expected to respond with a JSON object regardless of\nif the output parameters are empty.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{}" + } + }, + { + "id": "RestJsonIgnoreQueryParamsInResponseNoPayload", + "given": { + "name": "IgnoreQueryParamsInResponse", + "http": { + "method": "GET", + "requestUri": "/IgnoreQueryParamsInResponse", + "responseCode": 200 + }, + "output": { + "shape": "IgnoreQueryParamsInResponseOutput" + }, + "documentation": "This example ensures that query string bound request parameters are serialized in the body of responses if the structure is used in both the request and response.
" + }, + "description": "This test is similar to RestJsonIgnoreQueryParamsInResponse,\nbut it ensures that clients gracefully handle responses from\nthe server that do not serialize an empty JSON object.", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Attr": { - "shape": "StringType", - "jsonvalue": true, - "location": "header", - "locationName": "X-Amz-Foo" - } - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for InputAndOutputWithHeaders operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "InputAndOutputWithHeadersIO": { + "type": "structure", + "members": { + "headerString": { + "shape": "String", + "location": "header", + "locationName": "X-String" + }, + "headerByte": { + "shape": "Integer", + "location": "header", + "locationName": "X-Byte" + }, + "headerShort": { + "shape": "Integer", + "location": "header", + "locationName": "X-Short" + }, + "headerInteger": { + "shape": "Integer", + "location": "header", + "locationName": "X-Integer" + }, + "headerLong": { + "shape": "Long", + "location": "header", + "locationName": "X-Long" + }, + "headerFloat": { + "shape": "Float", + "location": "header", + "locationName": "X-Float" + }, + "headerDouble": { + "shape": "Double", + "location": "header", + "locationName": "X-Double" + }, + "headerTrueBool": { + "shape": "Boolean", + "location": "header", + "locationName": "X-Boolean1" + }, + "headerFalseBool": { + "shape": "Boolean", + "location": "header", + "locationName": "X-Boolean2" + }, + "headerStringList": { + "shape": "StringList", + "location": "header", + "locationName": "X-StringList" + }, + "headerStringSet": { + "shape": "StringSet", + "location": "header", + "locationName": "X-StringSet" + }, + "headerIntegerList": { + "shape": "IntegerList", + "location": "header", + "locationName": "X-IntegerList" + }, + "headerBooleanList": { + "shape": "BooleanList", + "location": "header", + "locationName": "X-BooleanList" + }, + "headerTimestampList": { + "shape": "TimestampList", + "location": "header", + "locationName": "X-TimestampList" + }, + "headerEnum": { + "shape": "FooEnum", + "location": "header", + "locationName": "X-Enum" + }, + "headerEnumList": { + "shape": "FooEnumList", + "location": "header", + "locationName": "X-EnumList" + }, + "headerIntegerEnum": { + "shape": "IntegerEnum", + "location": "header", + "locationName": "X-IntegerEnum" + }, + "headerIntegerEnumList": { + "shape": "IntegerEnumList", + "location": "header", + "locationName": "X-IntegerEnumList" + } + } + }, + "String": { + "type": "string" + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "Timestamp": { + "type": "timestamp" + } + }, + "cases": [ + { + "id": "RestJsonInputAndOutputWithStringHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with string header bindings", + "result": { + "headerString": "Hello", + "headerStringList": [ + "a", + "b", + "c" + ], + "headerStringSet": [ + "a", + "b", + "c" + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-String": "Hello", + "X-StringList": "a, b, c", + "X-StringSet": "a, b, c" + } + } + }, + { + "id": "RestJsonInputAndOutputWithQuotedStringHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with string list header bindings that require quoting", + "result": { + "headerStringList": [ + "b,c", + "\"def\"", + "a" + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-StringList": "\"b,c\", \"\\\"def\\\"\", a" + } + } + }, + { + "id": "RestJsonInputAndOutputWithNumericHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with numeric header bindings", + "result": { + "headerByte": 1, + "headerShort": 123, + "headerInteger": 123, + "headerLong": 123, + "headerFloat": 1.1, + "headerDouble": 1.1, + "headerIntegerList": [ + 1, + 2, + 3 + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Byte": "1", + "X-Double": "1.1", + "X-Float": "1.1", + "X-Integer": "123", + "X-IntegerList": "1, 2, 3", + "X-Long": "123", + "X-Short": "123" + } + } + }, + { + "id": "RestJsonInputAndOutputWithBooleanHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with boolean header bindings", + "result": { + "headerTrueBool": true, + "headerFalseBool": false, + "headerBooleanList": [ + true, + false, + true + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Boolean1": "true", + "X-Boolean2": "false", + "X-BooleanList": "true, false, true" + } + } + }, + { + "id": "RestJsonInputAndOutputWithTimestampHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with timestamp header bindings", + "result": { + "headerTimestampList": [ + 1576540098, + 1576540098 + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-TimestampList": "Mon, 16 Dec 2019 23:48:18 GMT, Mon, 16 Dec 2019 23:48:18 GMT" + } + } + }, + { + "id": "RestJsonInputAndOutputWithEnumHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with enum header bindings", + "result": { + "headerEnum": "Foo", + "headerEnumList": [ + "Foo", + "Bar", + "Baz" + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Enum": "Foo", + "X-EnumList": "Foo, Bar, Baz" + } + } + }, + { + "id": "RestJsonInputAndOutputWithIntEnumHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with intEnum header bindings", + "result": { + "headerIntegerEnum": 1, + "headerIntegerEnumList": [ + 1, + 2, + 3 + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-IntegerEnum": "1", + "X-IntegerEnumList": "1, 2, 3" + } + } + }, + { + "id": "RestJsonSupportsNaNFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Supports handling NaN float header values.", + "result": { + "headerFloat": "NaN", + "headerDouble": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "NaN", + "X-Float": "NaN" + } + } + }, + { + "id": "RestJsonSupportsInfinityFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Supports handling Infinity float header values.", + "result": { + "headerFloat": "Infinity", + "headerDouble": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "Infinity", + "X-Float": "Infinity" + } + } + }, + { + "id": "RestJsonSupportsNegativeInfinityFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Supports handling -Infinity float header values.", + "result": { + "headerFloat": "-Infinity", + "headerDouble": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "-Infinity", + "X-Float": "-Infinity" + } + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Attr": {"Foo":"Bar"} - }, - "response": { - "status_code": 200, - "headers": {"X-Amz-Foo": "eyJGb28iOiJCYXIifQ=="}, - "body": "" - } - } - ] - }, - { - "description": "Modeled exceptions", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for JsonBlobs operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonBlobsInputOutput": { + "type": "structure", + "members": { + "data": { + "shape": "Blob" + } + } + }, + "Blob": { + "type": "blob" + } + }, + "cases": [ + { + "id": "RestJsonJsonBlobs", + "given": { + "name": "JsonBlobs", + "http": { + "method": "POST", + "requestUri": "/JsonBlobs", + "responseCode": 200 + }, + "output": { + "shape": "JsonBlobsInputOutput" + }, + "documentation": "Blobs are base64 encoded
" + }, + "description": "Blobs are base64 encoded", + "result": { + "data": "value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"data\": \"dmFsdWU=\"\n}" + } + } + ] }, - "shapes": { - "ExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "ImaHeader": { - "shape": "HeaderShape" - }, - "ImaHeaderLocation": { - "shape": "HeaderShape", - "locationName": "X-Foo" - }, - "Status": { - "shape": "StatusShape", - "location": "statusCode" - }, - "BodyMember": { - "shape": "StringType" - }, - "Message": { - "shape": "StringType" - } - } - }, - "OtherExceptionShape": { - "exception": true, - "type": "structure", - "members": { - "BodyMember": { - "shape": "StringType" - } - } - }, - "HeaderShape": { - "type": "string", - "location": "header" - }, - "StatusShape": { - "type": "integer" - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for JsonEnums operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonEnumsInputOutput": { + "type": "structure", + "members": { + "fooEnum1": { + "shape": "FooEnum" + }, + "fooEnum2": { + "shape": "FooEnum" + }, + "fooEnum3": { + "shape": "FooEnum" + }, + "fooEnumList": { + "shape": "FooEnumList" + }, + "fooEnumSet": { + "shape": "FooEnumSet" + }, + "fooEnumMap": { + "shape": "FooEnumMap" + } + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumSet": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonJsonEnums", + "given": { + "name": "JsonEnums", + "http": { + "method": "PUT", + "requestUri": "/JsonEnums", + "responseCode": 200 + }, + "output": { + "shape": "JsonEnumsInputOutput" + }, + "documentation": "This example serializes enums as top level properties, in lists, sets, and maps.
", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"fooEnum1\": \"Foo\",\n \"fooEnum2\": \"0\",\n \"fooEnum3\": \"1\",\n \"fooEnumList\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumSet\": [\n \"Foo\",\n \"0\"\n ],\n \"fooEnumMap\": {\n \"hi\": \"Foo\",\n \"zero\": \"0\"\n }\n}" + } + } + ] }, - "cases": [ - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "ImaHeader": "test", - "ImaHeaderLocation": "abc", - "Status": 400, - "BodyMember": "mybody", - "Message": "mymessage" - }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc", - "X-Amzn-Errortype": "ExceptionShape" - }, - "body": "{\"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "ImaHeader": "test", - "ImaHeaderLocation": "abc", - "Status": 400, - "BodyMember": "mybody", - "Message": "mymessage" - }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc" - }, - "body": "{ \"code\": \"ExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "ImaHeader": "test", - "ImaHeaderLocation": "abc", - "Status": 400, - "BodyMember": "mybody", - "Message": "mymessage" - }, - "errorCode": "ExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc", - "X-Amzn-Errortype": "ExceptionShape" - }, - "body": "{ \"code\": \"OtherExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "BodyMember": "mybody" - }, - "errorCode": "OtherExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc", - "X-Amzn-Errortype": "OtherExceptionShape" - }, - "body": "{ \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": { - "BodyMember": "mybody" - }, - "errorCode": "OtherExceptionShape", - "errorMessage": "mymessage", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc" - }, - "body": "{ \"code\": \"OtherExceptionShape\", \"BodyMember\": \"mybody\", \"Message\": \"mymessage\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": {}, - "errorCode": "UndefinedShape", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc", - "X-Amzn-Errortype": "UndefinedShape" - }, - "body": "{ \"BodyMember\": \"mybody\"}" - } - }, - { - "given": { - "errors": [ - {"shape": "ExceptionShape"} - ], - "name": "OperationName" - }, - "error": {}, - "errorCode": "UndefinedShape", - "response": { - "status_code": 400, - "headers": { - "ImaHeader": "test", - "X-Foo": "abc" - }, - "body": "{ \"code\": \"UndefinedShape\", \"BodyMember\": \"mybody\"}" - } - } - ] - }, - { - "description": "Serializes document with standalone primitive as part of the JSON response payload with no escaping.", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for JsonIntEnums operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonIntEnumsInputOutput": { + "type": "structure", + "members": { + "integerEnum1": { + "shape": "IntegerEnum" + }, + "integerEnum2": { + "shape": "IntegerEnum" + }, + "integerEnum3": { + "shape": "IntegerEnum" + }, + "integerEnumList": { + "shape": "IntegerEnumList" + }, + "integerEnumSet": { + "shape": "IntegerEnumSet" + }, + "integerEnumMap": { + "shape": "IntegerEnumMap" + } + } + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumSet": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "IntegerEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "IntegerEnum" + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "RestJsonJsonIntEnums", + "given": { + "name": "JsonIntEnums", + "http": { + "method": "PUT", + "requestUri": "/JsonIntEnums", + "responseCode": 200 + }, + "output": { + "shape": "JsonIntEnumsInputOutput" + }, + "documentation": "This example serializes intEnums as top level properties, in lists, sets, and maps.
", + "idempotent": true + }, + "description": "Serializes intEnums as integers", + "result": { + "integerEnum1": 1, + "integerEnum2": 2, + "integerEnum3": 3, + "integerEnumList": [ + 1, + 2, + 3 + ], + "integerEnumSet": [ + 1, + 2 + ], + "integerEnumMap": { + "abc": 1, + "def": 2 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"integerEnum1\": 1,\n \"integerEnum2\": 2,\n \"integerEnum3\": 3,\n \"integerEnumList\": [\n 1,\n 2,\n 3\n ],\n \"integerEnumSet\": [\n 1,\n 2\n ],\n \"integerEnumMap\": {\n \"abc\": 1,\n \"def\": 2\n }\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "documentValue": { - "shape": "DocumentType" - } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + { + "description": "Test cases for JsonLists operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonListsInputOutput": { + "type": "structure", + "members": { + "stringList": { + "shape": "StringList" + }, + "stringSet": { + "shape": "StringSet" + }, + "integerList": { + "shape": "IntegerList" + }, + "booleanList": { + "shape": "BooleanList" + }, + "timestampList": { + "shape": "TimestampList" + }, + "enumList": { + "shape": "FooEnumList" + }, + "intEnumList": { + "shape": "IntegerEnumList" + }, + "nestedStringList": { + "shape": "NestedStringList" + }, + "structureList": { + "shape": "StructureList", + "locationName": "myStructureList" + } + } + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringSet": { + "type": "list", + "member": { + "shape": "String" + } + }, + "IntegerList": { + "type": "list", + "member": { + "shape": "Integer" + } + }, + "BooleanList": { + "type": "list", + "member": { + "shape": "Boolean" + } + }, + "TimestampList": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "FooEnumList": { + "type": "list", + "member": { + "shape": "FooEnum" + } + }, + "IntegerEnumList": { + "type": "list", + "member": { + "shape": "IntegerEnum" + } + }, + "NestedStringList": { + "type": "list", + "member": { + "shape": "StringList" + }, + "documentation": "A list of lists of strings.
" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "RestJsonLists", + "given": { + "name": "JsonLists", + "http": { + "method": "PUT", + "requestUri": "/JsonLists", + "responseCode": 200 + }, + "output": { + "shape": "JsonListsInputOutput" + }, + "documentation": "This test case serializes JSON lists for the following cases for both input and output:
This test case serializes JSON lists for the following cases for both input and output:
The example tests basic map serialization.
" + }, + "description": "Deserializes JSON maps", + "result": { + "denseStructMap": { + "foo": { + "hi": "there" + }, + "baz": { + "hi": "bye" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"denseStructMap\": {\n \"foo\": {\n \"hi\": \"there\"\n },\n \"baz\": {\n \"hi\": \"bye\"\n }\n }\n}" + } + }, + { + "id": "RestJsonDeserializesZeroValuesInMaps", + "given": { + "name": "JsonMaps", + "http": { + "method": "POST", + "requestUri": "/JsonMaps", + "responseCode": 200 + }, + "output": { + "shape": "JsonMapsInputOutput" + }, + "documentation": "The example tests basic map serialization.
" + }, + "description": "Ensure that 0 and false are sent over the wire in all maps and lists", + "result": { + "denseNumberMap": { + "x": 0 + }, + "denseBooleanMap": { + "x": false + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"denseNumberMap\": {\n \"x\": 0\n },\n \"denseBooleanMap\": {\n \"x\": false\n }\n}" + } + }, + { + "id": "RestJsonDeserializesDenseSetMap", + "given": { + "name": "JsonMaps", + "http": { + "method": "POST", + "requestUri": "/JsonMaps", + "responseCode": 200 + }, + "output": { + "shape": "JsonMapsInputOutput" + }, + "documentation": "The example tests basic map serialization.
" + }, + "description": "A response that contains a dense map of sets.", + "result": { + "denseSetMap": { + "x": [], + "y": [ + "a", + "b" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"denseSetMap\": {\n \"x\": [],\n \"y\": [\"a\", \"b\"]\n }\n}" + } + }, + { + "id": "RestJsonDeserializesDenseSetMapAndSkipsNull", + "given": { + "name": "JsonMaps", + "http": { + "method": "POST", + "requestUri": "/JsonMaps", + "responseCode": 200 + }, + "output": { + "shape": "JsonMapsInputOutput" + }, + "documentation": "The example tests basic map serialization.
" + }, + "description": "Clients SHOULD tolerate seeing a null value in a dense map, and they SHOULD\ndrop the null key-value pair.", + "result": { + "denseSetMap": { + "x": [], + "y": [ + "a", + "b" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"denseSetMap\": {\n \"x\": [],\n \"y\": [\"a\", \"b\"],\n \"z\": null\n }\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "documentValue": { - "shape": "DocumentType" - } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + { + "description": "Test cases for JsonTimestamps operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "JsonTimestampsInputOutput": { + "type": "structure", + "members": { + "normal": { + "shape": "Timestamp" + }, + "dateTime": { + "shape": "SyntheticTimestamp_date_time" + }, + "dateTimeOnTarget": { + "shape": "DateTime" + }, + "epochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds" + }, + "epochSecondsOnTarget": { + "shape": "EpochSeconds" + }, + "httpDate": { + "shape": "SyntheticTimestamp_http_date" + }, + "httpDateOnTarget": { + "shape": "HttpDate" + } + } + }, + "Timestamp": { + "type": "timestamp" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + } + }, + "cases": [ + { + "id": "RestJsonJsonTimestamps", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Tests how normal timestamps are serialized", + "result": { + "normal": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"normal\": 1398796238\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithDateTimeFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of date-time works like normal timestamps", + "result": { + "dateTime": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"dateTime\": \"2014-04-29T18:30:38Z\"\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithDateTimeOnTargetFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "result": { + "dateTimeOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"dateTimeOnTarget\": \"2014-04-29T18:30:38Z\"\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithEpochSecondsFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of epoch-seconds works", + "result": { + "epochSeconds": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"epochSeconds\": 1398796238\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithEpochSecondsOnTargetFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "result": { + "epochSecondsOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"epochSecondsOnTarget\": 1398796238\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithHttpDateFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of http-date works", + "result": { + "httpDate": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"httpDate\": \"Tue, 29 Apr 2014 18:30:38 GMT\"\n}" + } + }, + { + "id": "RestJsonJsonTimestampsWithHttpDateOnTargetFormat", + "given": { + "name": "JsonTimestamps", + "http": { + "method": "POST", + "requestUri": "/JsonTimestamps", + "responseCode": 200 + }, + "output": { + "shape": "JsonTimestampsInputOutput" + }, + "documentation": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of http-date on the target shape works", + "result": { + "httpDateOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"httpDateOnTarget\": \"Tue, 29 Apr 2014 18:30:38 GMT\"\n}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "documentValue": {"foo": "bar"} - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"documentValue\": {\"foo\": \"bar\"}}" - } - } - ] - }, - { - "description": "Serializes aggregate documents as part of the JSON response payload with no escaping.", - "metadata": { - "protocol": "rest-json", - "apiVersion": "2014-01-01" + { + "description": "Test cases for JsonUnions operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "UnionInputOutput": { + "type": "structure", + "members": { + "contents": { + "shape": "MyUnion" + } + }, + "documentation": "A shared structure that contains a single union member.
" + }, + "MyUnion": { + "type": "structure", + "members": { + "stringValue": { + "shape": "String" + }, + "booleanValue": { + "shape": "Boolean" + }, + "numberValue": { + "shape": "Integer" + }, + "blobValue": { + "shape": "Blob" + }, + "timestampValue": { + "shape": "Timestamp" + }, + "enumValue": { + "shape": "FooEnum" + }, + "listValue": { + "shape": "StringList" + }, + "mapValue": { + "shape": "StringMap" + }, + "structureValue": { + "shape": "GreetingStruct" + }, + "renamedStructureValue": { + "shape": "RenamedGreeting" + } + }, + "documentation": "A union with a representative set of types for members.
", + "union": true + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Blob": { + "type": "blob" + }, + "Timestamp": { + "type": "timestamp" + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "StringList": { + "type": "list", + "member": { + "shape": "String" + } + }, + "StringMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "String" + } + }, + "GreetingStruct": { + "type": "structure", + "members": { + "hi": { + "shape": "String" + } + } + }, + "RenamedGreeting": { + "type": "structure", + "members": { + "salutation": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "RestJsonDeserializeStringUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a string union value", + "result": { + "contents": { + "stringValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"stringValue\": \"foo\"\n }\n}" + } + }, + { + "id": "RestJsonDeserializeBooleanUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a boolean union value", + "result": { + "contents": { + "booleanValue": true + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"booleanValue\": true\n }\n}" + } + }, + { + "id": "RestJsonDeserializeNumberUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a number union value", + "result": { + "contents": { + "numberValue": 1 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"numberValue\": 1\n }\n}" + } + }, + { + "id": "RestJsonDeserializeBlobUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a blob union value", + "result": { + "contents": { + "blobValue": "foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"blobValue\": \"Zm9v\"\n }\n}" + } + }, + { + "id": "RestJsonDeserializeTimestampUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a timestamp union value", + "result": { + "contents": { + "timestampValue": 1398796238 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"timestampValue\": 1398796238\n }\n}" + } + }, + { + "id": "RestJsonDeserializeEnumUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes an enum union value", + "result": { + "contents": { + "enumValue": "Foo" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"enumValue\": \"Foo\"\n }\n}" + } + }, + { + "id": "RestJsonDeserializeListUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a list union value", + "result": { + "contents": { + "listValue": [ + "foo", + "bar" + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"listValue\": [\"foo\", \"bar\"]\n }\n}" + } + }, + { + "id": "RestJsonDeserializeMapUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a map union value", + "result": { + "contents": { + "mapValue": { + "foo": "bar", + "spam": "eggs" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"mapValue\": {\n \"foo\": \"bar\",\n \"spam\": \"eggs\"\n }\n }\n}" + } + }, + { + "id": "RestJsonDeserializeStructureUnionValue", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Deserializes a structure union value", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + }, + { + "id": "RestJsonDeserializeIgnoreType", + "given": { + "name": "JsonUnions", + "http": { + "method": "PUT", + "requestUri": "/JsonUnions", + "responseCode": 200 + }, + "output": { + "shape": "UnionInputOutput" + }, + "documentation": "This operation uses unions for inputs and outputs.
", + "idempotent": true + }, + "description": "Ignores an unrecognized __type property", + "result": { + "contents": { + "structureValue": { + "hi": "hello" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"contents\": {\n \"__type\": \"aws.protocoltests.json10#MyUnion\",\n \"structureValue\": {\n \"hi\": \"hello\"\n }\n }\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "documentValue": { - "shape": "DocumentType" - } - } - }, - "DocumentType": { - "type": "structure", - "document": true - } + { + "description": "Test cases for MediaTypeHeader operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "MediaTypeHeaderOutput": { + "type": "structure", + "members": { + "json": { + "shape": "JsonValue", + "jsonvalue": true, + "location": "header", + "locationName": "X-Json" + } + } + }, + "JsonValue": { + "type": "string" + } + }, + "cases": [ + { + "id": "MediaTypeHeaderOutputBase64", + "given": { + "name": "MediaTypeHeader", + "http": { + "method": "GET", + "requestUri": "/MediaTypeHeader", + "responseCode": 200 + }, + "output": { + "shape": "MediaTypeHeaderOutput" + }, + "documentation": "This example ensures that mediaType strings are base64 encoded in headers.
" + }, + "description": "Headers that target strings with a mediaType are base64 encoded", + "result": { + "json": "true" + }, + "response": { + "status_code": 200, + "headers": { + "X-Json": "dHJ1ZQ==" + } + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "documentValue": { - "str": "test", - "num": 123, - "float": 1.2, - "bool": true, - "null": "", - "document": {"foo": false}, - "list": ["myname", 321, 1.3, true, "", {"nested": true}, [200, ""]] - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"documentValue\": {\"str\": \"test\", \"num\": 123, \"float\": 1.2, \"bool\": true, \"null\": \"\", \"document\": {\"foo\": false}, \"list\": [\"myname\", 321, 1.3, true, \"\", {\"nested\": true}, [200, \"\"]]}}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "documentValue": [ - "test", - 123, - 1.2, - true, - "", - {"str": "myname", "num": 321, "float": 1.3, "bool": true, "null": "", "document": {"nested": true}, "list": [200, ""]}, - ["foo", false] - ] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"documentValue\": [\"test\", 123, 1.2, true, \"\", {\"str\": \"myname\", \"num\": 321, \"float\": 1.3, \"bool\": true, \"null\": \"\", \"document\": {\"nested\": true}, \"list\": [200, \"\"]}, [\"foo\", false]]}" - } - } - ] - }, - { - "description": "Tagged Unions", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for NoInputAndNoOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "RestJsonNoInputAndNoOutput", + "given": { + "name": "NoInputAndNoOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndNoOutput", + "responseCode": 200 + }, + "documentation": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.
" + }, + "description": "When an operation does not define output, the service will respond\nwith an empty payload, and may optionally include the content-type\nheader.", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "UnionMember": { - "shape": "UnionType" - } - } - }, - "UnionType": { - "type": "structure", - "members": { - "S":{"shape":"StringType"}, - "L": {"shape": "ListType"} - }, - "union": true - }, - "ListType": { - "type": "list", - "member": { - "shape": "StringType" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "NoInputAndOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "RestJsonNoInputAndOutputWithJson", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndOutputOutput", + "responseCode": 200 + }, + "output": { + "shape": "NoInputAndOutputOutput" + }, + "documentation": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input and the output is empty. While this should be rare, code generators must support this.
" + }, + "description": "Operations that define output and do not bind anything to\nthe payload return a JSON object in the response.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{}" + } + }, + { + "id": "RestJsonNoInputAndOutputNoPayload", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndOutputOutput", + "responseCode": 200 + }, + "output": { + "shape": "NoInputAndOutputOutput" + }, + "documentation": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input and the output is empty. While this should be rare, code generators must support this.
" + }, + "description": "This test is similar to RestJsonNoInputAndOutputWithJson, but\nit ensures that clients can gracefully handle responses that\nomit a JSON payload.", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "UnionMember": {"S": "mystring"} - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"UnionMember\": {\"S\": \"mystring\"}}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "UnionMember": {"L": ["a", "b"]} - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"UnionMember\": {\"L\": [\"a\", \"b\"]}}" - } - }, - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "UnionMember": {"SDK_UNKNOWN_MEMBER": {"name": "SomeUnknownMember"}} - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "{\"UnionMember\": {\"SomeUnknownMember\": \"foo\"}}" - } - } - ] - }, - { - "description": "List in header", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for PostUnionWithJsonName operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "PostUnionWithJsonNameOutput": { + "type": "structure", + "required": [ + "value" + ], + "members": { + "value": { + "shape": "UnionWithJsonName" + } + } + }, + "UnionWithJsonName": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "locationName": "FOO" + }, + "bar": { + "shape": "String" + }, + "baz": { + "shape": "String", + "locationName": "_baz" + } + }, + "union": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "PostUnionWithJsonNameResponse1", + "given": { + "name": "PostUnionWithJsonName", + "http": { + "method": "POST", + "requestUri": "/PostUnionWithJsonName", + "responseCode": 200 + }, + "output": { + "shape": "PostUnionWithJsonNameOutput" + }, + "documentation": "This operation defines a union that uses jsonName on some members.
" + }, + "description": "Tests that jsonName works with union members.", + "result": { + "value": { + "foo": "hi" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"value\": {\n \"FOO\": \"hi\"\n }\n}" + } + }, + { + "id": "PostUnionWithJsonNameResponse2", + "given": { + "name": "PostUnionWithJsonName", + "http": { + "method": "POST", + "requestUri": "/PostUnionWithJsonName", + "responseCode": 200 + }, + "output": { + "shape": "PostUnionWithJsonNameOutput" + }, + "documentation": "This operation defines a union that uses jsonName on some members.
" + }, + "description": "Tests that jsonName works with union members.", + "result": { + "value": { + "baz": "hi" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"value\": {\n \"_baz\": \"hi\"\n }\n}" + } + }, + { + "id": "PostUnionWithJsonNameResponse3", + "given": { + "name": "PostUnionWithJsonName", + "http": { + "method": "POST", + "requestUri": "/PostUnionWithJsonName", + "responseCode": 200 + }, + "output": { + "shape": "PostUnionWithJsonNameOutput" + }, + "documentation": "This operation defines a union that uses jsonName on some members.
" + }, + "description": "Tests that jsonName works with union members.", + "result": { + "value": { + "bar": "hi" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"value\": {\n \"bar\": \"hi\"\n }\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "ListMember": { - "shape": "ListShape", - "location": "header", - "locationName": "x-amz-list-member" - } - } - }, - "ListShape": { - "type": "list", - "member": { - "shape": "EnumType" - } - }, - "EnumType": { - "type": "string", - "enum": ["one", "two", "three"] - } + { + "description": "Test cases for RecursiveShapes operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "RecursiveShapesInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "RecursiveShapesInputOutputNested1" + } + } + }, + "RecursiveShapesInputOutputNested1": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "nested": { + "shape": "RecursiveShapesInputOutputNested2" + } + } + }, + "String": { + "type": "string" + }, + "RecursiveShapesInputOutputNested2": { + "type": "structure", + "members": { + "bar": { + "shape": "String" + }, + "recursiveMember": { + "shape": "RecursiveShapesInputOutputNested1" + } + } + } + }, + "cases": [ + { + "id": "RestJsonRecursiveShapes", + "given": { + "name": "RecursiveShapes", + "http": { + "method": "PUT", + "requestUri": "/RecursiveShapes", + "responseCode": 200 + }, + "output": { + "shape": "RecursiveShapesInputOutput" + }, + "documentation": "Recursive shapes
", + "idempotent": true + }, + "description": "Serializes recursive structures", + "result": { + "nested": { + "foo": "Foo1", + "nested": { + "bar": "Bar1", + "recursiveMember": { + "foo": "Foo2", + "nested": { + "bar": "Bar2" + } + } + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"nested\": {\n \"foo\": \"Foo1\",\n \"nested\": {\n \"bar\": \"Bar1\",\n \"recursiveMember\": {\n \"foo\": \"Foo2\",\n \"nested\": {\n \"bar\": \"Bar2\"\n }\n }\n }\n }\n}" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["one", "two", "three"] - }, - "response": { - "status_code": 200, - "headers": { - "x-amz-list-member": " one,two , three " - }, - "body": "" - } - } - ] - }, - { - "description": "Number in header", - "metadata": { - "protocol": "rest-json" + { + "description": "Test cases for SimpleScalarProperties operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "SimpleScalarPropertiesInputOutput": { + "type": "structure", + "members": { + "foo": { + "shape": "String", + "location": "header", + "locationName": "X-Foo" + }, + "stringValue": { + "shape": "String" + }, + "trueBooleanValue": { + "shape": "Boolean" + }, + "falseBooleanValue": { + "shape": "Boolean" + }, + "byteValue": { + "shape": "Integer" + }, + "shortValue": { + "shape": "Integer" + }, + "integerValue": { + "shape": "Integer" + }, + "longValue": { + "shape": "Long" + }, + "floatValue": { + "shape": "Float" + }, + "doubleValue": { + "shape": "Double", + "locationName": "DoubleDribble" + } + } + }, + "String": { + "type": "string" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + }, + "Long": { + "type": "long", + "box": true + }, + "Float": { + "type": "float", + "box": true + }, + "Double": { + "type": "double", + "box": true + } + }, + "cases": [ + { + "id": "RestJsonSimpleScalarProperties", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "foo": "Foo", + "stringValue": "string", + "trueBooleanValue": true, + "falseBooleanValue": false, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json", + "X-Foo": "Foo" + }, + "body": "{\n \"stringValue\": \"string\",\n \"trueBooleanValue\": true,\n \"falseBooleanValue\": false,\n \"byteValue\": 1,\n \"shortValue\": 2,\n \"integerValue\": 3,\n \"longValue\": 4,\n \"floatValue\": 5.5,\n \"DoubleDribble\": 6.5\n}" + } + }, + { + "id": "RestJsonDoesntDeserializeNullStructureValues", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Rest Json should not deserialize null structure values", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"stringValue\": null\n}" + } + }, + { + "id": "RestJsonSupportsNaNFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Supports handling NaN float values.", + "result": { + "floatValue": "NaN", + "doubleValue": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"floatValue\": \"NaN\",\n \"DoubleDribble\": \"NaN\"\n}" + } + }, + { + "id": "RestJsonSupportsInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Supports handling Infinity float values.", + "result": { + "floatValue": "Infinity", + "doubleValue": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"floatValue\": \"Infinity\",\n \"DoubleDribble\": \"Infinity\"\n}" + } + }, + { + "id": "RestJsonSupportsNegativeInfinityFloatInputs", + "given": { + "name": "SimpleScalarProperties", + "http": { + "method": "PUT", + "requestUri": "/SimpleScalarProperties", + "responseCode": 200 + }, + "output": { + "shape": "SimpleScalarPropertiesInputOutput" + }, + "idempotent": true + }, + "description": "Supports handling -Infinity float values.", + "result": { + "floatValue": "-Infinity", + "doubleValue": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\n \"floatValue\": \"-Infinity\",\n \"DoubleDribble\": \"-Infinity\"\n}" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "IntegerMember": { - "shape": "IntegerShape", - "location": "header", - "locationName": "x-amz-integer-member" - }, - "LongMember": { - "shape": "LongShape", - "location": "header", - "locationName": "x-amz-long-member" - } - } - }, - "IntegerShape": { - "type": "integer" - }, - "LongShape": { - "type": "long" - } + { + "description": "Test cases for TimestampFormatHeaders operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "TimestampFormatHeadersIO": { + "type": "structure", + "members": { + "memberEpochSeconds": { + "shape": "SyntheticTimestamp_epoch_seconds", + "location": "header", + "locationName": "X-memberEpochSeconds" + }, + "memberHttpDate": { + "shape": "SyntheticTimestamp_http_date", + "location": "header", + "locationName": "X-memberHttpDate" + }, + "memberDateTime": { + "shape": "SyntheticTimestamp_date_time", + "location": "header", + "locationName": "X-memberDateTime" + }, + "defaultFormat": { + "shape": "Timestamp", + "location": "header", + "locationName": "X-defaultFormat" + }, + "targetEpochSeconds": { + "shape": "EpochSeconds", + "location": "header", + "locationName": "X-targetEpochSeconds" + }, + "targetHttpDate": { + "shape": "HttpDate", + "location": "header", + "locationName": "X-targetHttpDate" + }, + "targetDateTime": { + "shape": "DateTime", + "location": "header", + "locationName": "X-targetDateTime" + } + } + }, + "SyntheticTimestamp_epoch_seconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "SyntheticTimestamp_http_date": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "SyntheticTimestamp_date_time": { + "type": "timestamp", + "timestampFormat": "iso8601" + }, + "Timestamp": { + "type": "timestamp" + }, + "EpochSeconds": { + "type": "timestamp", + "timestampFormat": "unixTimestamp" + }, + "HttpDate": { + "type": "timestamp", + "timestampFormat": "rfc822" + }, + "DateTime": { + "type": "timestamp", + "timestampFormat": "iso8601" + } + }, + "cases": [ + { + "id": "RestJsonTimestampFormatHeaders", + "given": { + "name": "TimestampFormatHeaders", + "http": { + "method": "POST", + "requestUri": "/TimestampFormatHeaders", + "responseCode": 200 + }, + "output": { + "shape": "TimestampFormatHeadersIO" + }, + "documentation": "This example tests how timestamp request and response headers are serialized.
" + }, + "description": "Tests how timestamp response headers are serialized", + "result": { + "memberEpochSeconds": 1576540098, + "memberHttpDate": 1576540098, + "memberDateTime": 1576540098, + "defaultFormat": 1576540098, + "targetEpochSeconds": 1576540098, + "targetHttpDate": 1576540098, + "targetDateTime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "X-defaultFormat": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-memberDateTime": "2019-12-16T23:48:18Z", + "X-memberEpochSeconds": "1576540098", + "X-memberHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-targetDateTime": "2019-12-16T23:48:18Z", + "X-targetEpochSeconds": "1576540098", + "X-targetHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT" + } + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "IntegerMember": 123, - "LongMember": 200 - }, - "response": { - "status_code": 200, - "headers": { - "x-amz-integer-member": "123", - "x-amz-long-member": "200" - }, - "body": "" - } - } - ] - } + { + "description": "Test cases for UnitInputAndOutput operation", + "metadata": { + "protocol": "rest-json", + "protocols": [ + "rest-json" + ], + "apiVersion": "2019-12-16" + }, + "shapes": {}, + "cases": [ + { + "id": "RestJsonUnitInputAndOutputNoOutput", + "given": { + "name": "UnitInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/UnitInputAndOutput", + "responseCode": 200 + }, + "documentation": "This test is similar to NoInputAndNoOutput, but uses explicit Unit types.
" + }, + "description": "When an operation defines Unit output, the service will respond\nwith an empty payload, and may optionally include the content-type\nheader.", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] + } ] diff --git a/tests/unit/protocols/output/rest-xml.json b/tests/unit/protocols/output/rest-xml.json index 8da4680960..c048fedfe8 100644 --- a/tests/unit/protocols/output/rest-xml.json +++ b/tests/unit/protocols/output/rest-xml.json @@ -1,1273 +1,4627 @@ [ - { - "description": "Scalar members", - "metadata": { - "protocol": "rest-xml" + { + "description": "Test cases for BodyWithXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "BodyWithXmlNameInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlName" + } + }, + "locationName": "Ahoy" + }, + "PayloadWithXmlName": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "locationName": "Hello" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "BodyWithXmlName", + "given": { + "name": "BodyWithXmlName", + "http": { + "method": "PUT", + "requestUri": "/BodyWithXmlName", + "responseCode": 200 + }, + "output": { + "shape": "BodyWithXmlNameInputOutput" + }, + "documentation": "The following example serializes a body that uses an XML name, changing the wrapper name.
", + "idempotent": true + }, + "description": "Serializes a payload using a wrapper name based on the xmlName", + "result": { + "nested": { + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has an empty input and empty output structure that reuses the same shape. While this should be rare, code generators must support this.
" + }, + "description": "Empty output serializes no payload", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] + }, + { + "description": "Test cases for FlattenedXmlMap operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "FlattenedXmlMapResponse": { + "type": "structure", + "members": { + "myMap": { + "shape": "FooEnumMap", + "flattened": true + } + } + }, + "FooEnumMap": { + "type": "map", + "key": { + "shape": "String" + }, + "value": { + "shape": "FooEnum" + } + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "FlattenedXmlMap", + "given": { + "name": "FlattenedXmlMap", + "http": { + "method": "POST", + "requestUri": "/FlattenedXmlMap", + "responseCode": 200 + }, + "output": { + "shape": "FlattenedXmlMapResponse" + }, + "documentation": "Flattened maps
" + }, + "description": "Serializes flattened XML maps in responses", + "result": { + "myMap": { + "foo": "Foo", + "baz": "Baz" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "Flattened maps with @xmlName
" + }, + "description": "Serializes flattened XML maps in responses that have xmlName on members", + "result": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "Flattened maps with @xmlNamespace and @xmlName
" + }, + "description": "Serializes flattened XML maps in responses that have xmlNamespace and xmlName on members", + "result": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true + }, + "description": "Ensures that operations with errors successfully know how to deserialize the successful response", + "result": { + "greeting": "Hello" + }, + "response": { + "status_code": 200, + "headers": { + "X-Greeting": "Hello" + }, + "body": "" + } + } + ] + }, + { + "description": "Test cases for GreetingWithErrors operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "InvalidGreeting": { + "type": "structure", + "members": { + "Message": { + "shape": "String" + } + }, + "documentation": "This error is thrown when an invalid greeting value is provided.
", + "error": { + "httpStatusCode": 400, + "senderFault": true + }, + "exception": true + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "InvalidGreetingError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "InvalidGreeting" + } + ] + }, + "description": "Parses simple XML errors", + "errorCode": "InvalidGreeting", + "errorMessage": "Hi", + "error": { + "Message": "Hi" + }, + "response": { + "status_code": 400, + "headers": { + "Content-Type": "application/xml" + }, + "body": "InvalidGreeting
\n This error is thrown when a request is invalid.
", + "error": { + "httpStatusCode": 403, + "senderFault": true + }, + "exception": true + }, + "String": { + "type": "string" + }, + "ComplexNestedErrorData": { + "type": "structure", + "members": { + "Foo": { + "shape": "String" + } + } + } + }, + "cases": [ + { + "id": "ComplexError", + "given": { + "name": "GreetingWithErrors", + "http": { + "method": "PUT", + "requestUri": "/GreetingWithErrors", + "responseCode": 200 + }, + "documentation": "This operation has three possible return values:
Implementations must be able to successfully take a response and properly (de)serialize successful and error responses based on the the presence of the
", + "idempotent": true, + "errors": [ + { + "shape": "ComplexError" + } + ] + }, + "errorCode": "ComplexError", + "error": { + "Header": "Header", + "TopLevel": "Top level", + "Nested": { + "Foo": "bar" + } + }, + "response": { + "status_code": 403, + "headers": { + "Content-Type": "application/xml", + "X-Header": "Header" + }, + "body": "ComplexError
\n This example serializes a blob shape in the payload.
In this example, no XML document is synthesized because the payload is not a structure or a union type.
" + }, + "description": "Serializes a blob in the HTTP payload", + "result": { + "foo": "Foo", + "blob": "blobby blob blob" + }, + "response": { + "status_code": 200, + "headers": { + "X-Foo": "Foo" + }, + "body": "blobby blob blob" + } + }, + { + "id": "HttpPayloadTraitsWithNoBlobBody", + "given": { + "name": "HttpPayloadTraits", + "http": { + "method": "POST", + "requestUri": "/HttpPayloadTraits", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadTraitsInputOutput" + }, + "documentation": "This example serializes a blob shape in the payload.
In this example, no XML document is synthesized because the payload is not a structure or a union type.
" + }, + "description": "Serializes an empty blob in the HTTP payload", + "result": { + "foo": "Foo" + }, + "response": { + "status_code": 200, + "headers": { + "X-Foo": "Foo" + }, + "body": "" + } + } + ] + }, + { + "description": "Test cases for HttpPayloadWithMemberXmlName operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "HttpPayloadWithMemberXmlNameInputOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "PayloadWithXmlName", + "locationName": "Hola" + } + }, + "payload": "nested" + }, + "PayloadWithXmlName": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + }, + "locationName": "Hello" + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "HttpPayloadWithMemberXmlName", + "given": { + "name": "HttpPayloadWithMemberXmlName", + "http": { + "method": "PUT", + "requestUri": "/HttpPayloadWithMemberXmlName", + "responseCode": 200 + }, + "output": { + "shape": "HttpPayloadWithMemberXmlNameInputOutput" + }, + "documentation": "The following example serializes a payload that uses an XML name on the member, changing the wrapper name.
", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper name based on member xmlName", + "result": { + "nested": { + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This example serializes a structure in the payload.
Note that serializing a structure changes the wrapper element name to match the targeted structure.
", + "idempotent": true + }, + "description": "Serializes a structure in the payload", + "result": { + "nested": { + "greeting": "hello", + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This example serializes a union in the payload.
", + "idempotent": true + }, + "description": "Serializes a union in the payload.", + "result": { + "nested": { + "greeting": "hello" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This example serializes a union in the payload.
", + "idempotent": true + }, + "description": "No payload is sent if the union has no value.", + "result": {}, + "response": { + "status_code": 200, + "headers": { + "Content-Length": "0" + }, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Blob": "value" - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "The following example serializes a payload that uses an XML name, changing the wrapper name.
", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper name based on xmlName", + "result": { + "nested": { + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "The following example serializes a payload that uses an XML namespace.
", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper with an XML namespace", + "result": { + "nested": { + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "The following example serializes a payload that uses an XML namespace.
", + "idempotent": true + }, + "description": "Serializes a structure in the payload using a wrapper with an XML namespace", + "result": { + "nested": { + "name": "Phreddy" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This examples adds headers to the input of a request and response by prefix.
" + }, + "description": "Adds headers by prefix", + "result": { + "foo": "Foo", + "fooMap": { + "abc": "Abc value", + "def": "Def value" + } + }, + "response": { + "status_code": 200, + "headers": { + "x-foo": "Foo", + "x-foo-abc": "Abc value", + "x-foo-def": "Def value" + }, + "body": "" + } + }, + { + "id": "HttpPrefixHeadersAreNotPresent", + "given": { + "name": "HttpPrefixHeaders", + "http": { + "method": "GET", + "requestUri": "/HttpPrefixHeaders", + "responseCode": 200 + }, + "output": { + "shape": "HttpPrefixHeadersInputOutput" + }, + "documentation": "This examples adds headers to the input of a request and response by prefix.
" + }, + "description": "No prefix headers are serialized because the value is empty", + "result": { + "foo": "Foo", + "fooMap": {} + }, + "response": { + "status_code": 200, + "headers": { + "x-foo": "Foo" + }, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "ListMember": ["abc", "123"] - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "This example ensures that query string bound request parameters are serialized in the body of responses if the structure is used in both the request and response.
" + }, + "description": "Query parameters must be ignored when serializing the output of an operation", + "result": { + "baz": "bam" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with string header bindings", + "result": { + "headerString": "Hello", + "headerStringList": [ + "a", + "b", + "c" + ], + "headerStringSet": [ + "a", + "b", + "c" + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-String": "Hello", + "X-StringList": "a, b, c", + "X-StringSet": "a, b, c" + }, + "body": "" + } + }, + { + "id": "InputAndOutputWithNumericHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with numeric header bindings", + "result": { + "headerByte": 1, + "headerShort": 123, + "headerInteger": 123, + "headerLong": 123, + "headerFloat": 1.1, + "headerDouble": 1.1, + "headerIntegerList": [ + 1, + 2, + 3 + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Byte": "1", + "X-Double": "1.1", + "X-Float": "1.1", + "X-Integer": "123", + "X-IntegerList": "1, 2, 3", + "X-Long": "123", + "X-Short": "123" + }, + "body": "" + } + }, + { + "id": "InputAndOutputWithBooleanHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with boolean header bindings", + "result": { + "headerTrueBool": true, + "headerFalseBool": false, + "headerBooleanList": [ + true, + false, + true + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Boolean1": "true", + "X-Boolean2": "false", + "X-BooleanList": "true, false, true" + }, + "body": "" + } + }, + { + "id": "InputAndOutputWithTimestampHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with timestamp header bindings", + "result": { + "headerTimestampList": [ + 1576540098, + 1576540098 + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-TimestampList": "Mon, 16 Dec 2019 23:48:18 GMT, Mon, 16 Dec 2019 23:48:18 GMT" + }, + "body": "" + } + }, + { + "id": "InputAndOutputWithEnumHeaders", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Tests responses with enum header bindings", + "result": { + "headerEnum": "Foo", + "headerEnumList": [ + "Foo", + "Bar", + "Baz" + ] + }, + "response": { + "status_code": 200, + "headers": { + "X-Enum": "Foo", + "X-EnumList": "Foo, Bar, Baz" + }, + "body": "" + } + }, + { + "id": "RestXmlSupportsNaNFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Supports handling NaN float header values.", + "result": { + "headerFloat": "NaN", + "headerDouble": "NaN" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "NaN", + "X-Float": "NaN" + }, + "body": "" + } + }, + { + "id": "RestXmlSupportsInfinityFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Supports handling Infinity float header values.", + "result": { + "headerFloat": "Infinity", + "headerDouble": "Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "Infinity", + "X-Float": "Infinity" + }, + "body": "" + } + }, + { + "id": "RestXmlSupportsNegativeInfinityFloatHeaderOutputs", + "given": { + "name": "InputAndOutputWithHeaders", + "http": { + "method": "POST", + "requestUri": "/InputAndOutputWithHeaders", + "responseCode": 200 + }, + "output": { + "shape": "InputAndOutputWithHeadersIO" + }, + "documentation": "The example tests how requests and responses are serialized when there is no input or output payload but there are HTTP header bindings.
" + }, + "description": "Supports handling -Infinity float header values.", + "result": { + "headerFloat": "-Infinity", + "headerDouble": "-Infinity" + }, + "response": { + "status_code": 200, + "headers": { + "X-Double": "-Infinity", + "X-Float": "-Infinity" + }, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": { - "foo": "bar" - }, - "baz": { - "foo": "bam" - } - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "Nested Xml Maps with key/values with @xmlName
" + }, + "description": "Serializes nested XML maps in responses that have xmlName on members", + "result": { + "nestedXmlMapWithXmlNameMap": { + "foo": { + "bar": "Baz", + "fizz": "Buzz" + }, + "qux": { + "foobar": "Bar", + "fizzbuzz": "Buzz" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input or output. While this should be rare, code generators must support this.
" + }, + "description": "No output serializes no payload", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "members": { - "Map": { - "shape": "StringMap" - } - } - }, - "StringMap": { - "type": "map", - "key": { - "shape": "StringType", - "locationName": "foo" - }, - "value": { - "shape": "StringType", - "locationName": "bar" - } - }, - "StringType": { - "type": "string" - } + { + "description": "Test cases for NoInputAndOutput operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "NoInputAndOutputOutput": { + "type": "structure", + "members": {} + } + }, + "cases": [ + { + "id": "NoInputAndOutput", + "given": { + "name": "NoInputAndOutput", + "http": { + "method": "POST", + "requestUri": "/NoInputAndOutputOutput", + "responseCode": 200 + }, + "output": { + "shape": "NoInputAndOutputOutput" + }, + "documentation": "The example tests how requests and responses are serialized when there's no request or response payload because the operation has no input and the output is empty. While this should be rare, code generators must support this.
" + }, + "description": "Empty output serializes no payload", + "result": {}, + "response": { + "status_code": 200, + "body": "" + } + } + ] }, - "cases": [ - { - "given": { - "output": { - "shape": "OutputShape" - }, - "name": "OperationName" - }, - "result": { - "Map": { - "qux": "bar", - "baz": "bam" - } - }, - "response": { - "status_code": 200, - "headers": {}, - "body": "Recursive shapes
", + "idempotent": true + }, + "description": "Serializes recursive structures", + "result": { + "nested": { + "foo": "Foo1", + "nested": { + "bar": "Bar1", + "recursiveMember": { + "foo": "Foo2", + "nested": { + "bar": "Bar2" + } + } + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "The example tests how timestamp request and response headers are serialized.
" + }, + "description": "Tests how timestamp response headers are serialized", + "result": { + "memberEpochSeconds": 1576540098, + "memberHttpDate": 1576540098, + "memberDateTime": 1576540098, + "defaultFormat": 1576540098, + "targetEpochSeconds": 1576540098, + "targetHttpDate": 1576540098, + "targetDateTime": 1576540098 + }, + "response": { + "status_code": 200, + "headers": { + "X-defaultFormat": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-memberDateTime": "2019-12-16T23:48:18Z", + "X-memberEpochSeconds": "1576540098", + "X-memberHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-targetDateTime": "2019-12-16T23:48:18Z", + "X-targetEpochSeconds": "1576540098", + "X-targetHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT" + }, + "body": "" + } + } + ] }, - "shapes": { - "OutputShape": { - "type": "structure", - "payload": "Stream", - "members": { - "Stream": { - "shape": "BlobStream" - } - } - }, - "BlobStream": { - "type": "blob" - } + { + "description": "Test cases for XmlAttributes operation", + "metadata": { + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "apiVersion": "2019-12-16" + }, + "shapes": { + "XmlAttributesResponse": { + "type": "structure", + "members": { + "foo": { + "shape": "String" + }, + "attr": { + "shape": "String", + "locationName": "test", + "xmlAttribute": true + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XmlAttributes", + "given": { + "name": "XmlAttributes", + "http": { + "method": "PUT", + "requestUri": "/XmlAttributes", + "responseCode": 200 + }, + "output": { + "shape": "XmlAttributesResponse" + }, + "documentation": "This example serializes an XML attributes on synthesized document.
", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "foo": "hi", + "attr": "test" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This example serializes an XML attributes on a document targeted by httpPayload.
", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "payload": { + "foo": "hi", + "attr": "test" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "Blobs are base64 encoded
" + }, + "description": "Blobs are base64 encoded", + "result": { + "data": "value" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "Blobs are base64 encoded
" + }, + "description": "Empty blobs are deserialized as empty string", + "result": { + "data": "" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "Blobs are base64 encoded
" + }, + "description": "Empty self closed blobs are deserialized as empty string", + "result": { + "data": "" + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "A list of lists of strings.
" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "XmlEmptyLists", + "given": { + "name": "XmlEmptyLists", + "http": { + "method": "PUT", + "requestUri": "/XmlEmptyLists", + "responseCode": 200 + }, + "output": { + "shape": "XmlEmptyListsResponse" + }, + "idempotent": true + }, + "description": "Deserializes Empty XML lists", + "result": { + "stringList": [], + "stringSet": [] + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This example serializes enums as top level properties, in lists, sets, and maps.
", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": [ + "Foo", + "0" + ], + "fooEnumSet": [ + "Foo", + "0" + ], + "fooEnumMap": { + "hi": "Foo", + "zero": "0" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This example serializes enums as top level properties, in lists, sets, and maps.
", + "idempotent": true + }, + "description": "Serializes simple scalar properties", + "result": { + "intEnum1": 1, + "intEnum2": 2, + "intEnum3": 3, + "intEnumList": [ + 1, + 2 + ], + "intEnumSet": [ + 1, + 2 + ], + "intEnumMap": { + "a": 1, + "b": 2 + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "A list of lists of strings.
" + }, + "RenamedListMembers": { + "type": "list", + "member": { + "shape": "String", + "locationName": "item" + } + }, + "ListWithMemberNamespace": { + "type": "list", + "member": { + "shape": "String", + "xmlNamespace": "https://xml-member.example.com" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "ListWithNamespace": { + "type": "list", + "member": { + "shape": "String" + }, + "xmlNamespace": "https://xml-list.example.com" + }, + "StructureList": { + "type": "list", + "member": { + "shape": "StructureListMember", + "locationName": "item" + } + }, + "StructureListMember": { + "type": "structure", + "members": { + "a": { + "shape": "String", + "locationName": "value" + }, + "b": { + "shape": "String", + "locationName": "other" + } + } + }, + "String": { + "type": "string" + }, + "IntegerEnum": { + "type": "integer", + "box": true + }, + "FooEnum": { + "type": "string", + "enum": [ + "Foo", + "Baz", + "Bar", + "1", + "0" + ] + }, + "Timestamp": { + "type": "timestamp" + }, + "Boolean": { + "type": "boolean", + "box": true + }, + "Integer": { + "type": "integer", + "box": true + } + }, + "cases": [ + { + "id": "XmlLists", + "given": { + "name": "XmlLists", + "http": { + "method": "PUT", + "requestUri": "/XmlLists", + "responseCode": 200 + }, + "output": { + "shape": "XmlListsResponse" + }, + "documentation": "This test case serializes XML lists for the following cases for both input and output:
The example tests basic map serialization.
" + }, + "description": "Tests for XML map serialization", + "result": { + "myMap": { + "foo": { + "hi": "there" + }, + "baz": { + "hi": "bye" + } + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "Maps with @xmlNamespace and @xmlName
" + }, + "description": "Serializes XML maps in responses that have xmlNamespace and xmlName on members", + "result": { + "myMap": { + "a": "A", + "b": "B" + } + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "ExceptionShape
OtherExceptionShape
UndefinedShape
This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Tests how normal timestamps are serialized", + "result": { + "normal": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of date-time works like normal timestamps", + "result": { + "dateTime": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "result": { + "dateTimeOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of epoch-seconds works", + "result": { + "epochSeconds": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "result": { + "epochSecondsOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of http-date works", + "result": { + "httpDate": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "This tests how timestamps are serialized, including using the default format of date-time and various @timestampFormat trait values.
" + }, + "description": "Ensures that the timestampFormat of http-date on the target shape works", + "result": { + "httpDateOnTarget": 1398796238 + }, + "response": { + "status_code": 200, + "headers": { + "Content-Type": "application/xml" + }, + "body": "