// This file defines test cases that serialize synthesized XML documents // in the payload of HTTP requests and responses. $version: "2.0" namespace aws.protocoltests.restxml use aws.protocols#restXml use aws.protocoltests.shared#DateTime use aws.protocoltests.shared#EpochSeconds use aws.protocoltests.shared#FooEnum use aws.protocoltests.shared#FooEnumList use aws.protocoltests.shared#FooEnumSet use aws.protocoltests.shared#FooEnumMap use aws.protocoltests.shared#IntegerEnum use aws.protocoltests.shared#IntegerEnumList use aws.protocoltests.shared#IntegerEnumSet use aws.protocoltests.shared#IntegerEnumMap use aws.protocoltests.shared#HttpDate use smithy.test#httpRequestTests use smithy.test#httpResponseTests // This example serializes simple scalar types in the top level XML document. // Note that headers are not serialized in the payload. @idempotent @http(uri: "/SimpleScalarProperties", method: "PUT") operation SimpleScalarProperties { input: SimpleScalarPropertiesInputOutput, output: SimpleScalarPropertiesInputOutput } apply SimpleScalarProperties @httpRequestTests([ { id: "SimpleScalarProperties", documentation: "Serializes simple scalar properties", protocol: restXml, method: "PUT", uri: "/SimpleScalarProperties", body: """ string true false 1 2 3 4 5.5 6.5 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml", "X-Foo": "Foo", }, params: { foo: "Foo", stringValue: "string", trueBooleanValue: true, falseBooleanValue: false, byteValue: 1, shortValue: 2, integerValue: 3, longValue: 4, floatValue: 5.5, doubleValue: 6.5, } }, { id: "SimpleScalarPropertiesWithEscapedCharacter", documentation: "Serializes string with escaping", protocol: restXml, method: "PUT", uri: "/SimpleScalarProperties", body: """ <string> """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml", "X-Foo": "Foo", }, params: { foo: "Foo", stringValue: "", } }, { id: "SimpleScalarPropertiesWithWhiteSpace", documentation: "Serializes string containing white space", protocol: restXml, method: "PUT", uri: "/SimpleScalarProperties", body: """ string with white space """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml", "X-Foo": "Foo", }, params: { foo: "Foo", stringValue: " string with white space ", } }, { id: "SimpleScalarPropertiesPureWhiteSpace", documentation: "Serializes string containing exclusively whitespace", protocol: restXml, method: "PUT", uri: "/SimpleScalarProperties", body: """ """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml", "X-Foo": "Foo", }, params: { foo: "Foo", stringValue: " ", } }, { id: "RestXmlSupportsNaNFloatInputs", documentation: "Supports handling NaN float values.", protocol: restXml, method: "PUT", uri: "/SimpleScalarProperties", body: """ NaN NaN """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { floatValue: "NaN", doubleValue: "NaN", } }, { id: "RestXmlSupportsInfinityFloatInputs", documentation: "Supports handling Infinity float values.", protocol: restXml, method: "PUT", uri: "/SimpleScalarProperties", body: """ Infinity Infinity """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { floatValue: "Infinity", doubleValue: "Infinity", } }, { id: "RestXmlSupportsNegativeInfinityFloatInputs", documentation: "Supports handling -Infinity float values.", protocol: restXml, method: "PUT", uri: "/SimpleScalarProperties", body: """ -Infinity -Infinity """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { floatValue: "-Infinity", doubleValue: "-Infinity", } }, ]) apply SimpleScalarProperties @httpResponseTests([ { id: "SimpleScalarProperties", documentation: "Serializes simple scalar properties", protocol: restXml, code: 200, body: """ string true false 1 2 3 4 5.5 6.5 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml", "X-Foo": "Foo", }, params: { foo: "Foo", stringValue: "string", trueBooleanValue: true, falseBooleanValue: false, byteValue: 1, shortValue: 2, integerValue: 3, longValue: 4, floatValue: 5.5, doubleValue: 6.5, } }, { id: "SimpleScalarPropertiesComplexEscapes", documentation: """ Serializes string with escaping. This validates the three escape types: literal, decimal and hexadecimal. It also validates that unescaping properly handles the case where unescaping an & produces a newly formed escape sequence (this should not be re-unescaped). Servers may produce different output, this test is designed different unescapes clients must handle """, protocol: restXml, code: 200, body: """ escaped data: &lt; """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml", "X-Foo": "Foo", }, params: { foo: "Foo", stringValue: "escaped data: <\r\n", }, appliesTo: "client", }, { id: "SimpleScalarPropertiesWithEscapedCharacter", documentation: "Serializes string with escaping", protocol: restXml, code: 200, body: """ <string> """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml", "X-Foo": "Foo", }, params: { foo: "Foo", stringValue: "", } }, { id: "SimpleScalarPropertiesWithXMLPreamble", documentation: "Serializes simple scalar properties with xml preamble, comments and CDATA", protocol: restXml, code: 200, body: """ string """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml", "X-Foo": "Foo", }, params: { foo: "Foo", stringValue: "string", } }, { id: "SimpleScalarPropertiesWithWhiteSpace", documentation: "Serializes string containing white space", protocol: restXml, code: 200, body: """ string with white space """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml", "X-Foo": "Foo", }, params: { foo: "Foo", stringValue: " string with white space ", } }, { id: "SimpleScalarPropertiesPureWhiteSpace", documentation: "Serializes string containing white space", protocol: restXml, code: 200, body: """ """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml", "X-Foo": "Foo", }, params: { foo: "Foo", stringValue: " ", } }, { id: "RestXmlSupportsNaNFloatOutputs", documentation: "Supports handling NaN float values.", protocol: restXml, code: 200, body: """ NaN NaN """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { floatValue: "NaN", doubleValue: "NaN", } }, { id: "RestXmlSupportsInfinityFloatOutputs", documentation: "Supports handling Infinity float values.", protocol: restXml, code: 200, body: """ Infinity Infinity """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { floatValue: "Infinity", doubleValue: "Infinity", } }, { id: "RestXmlSupportsNegativeInfinityFloatOutputs", documentation: "Supports handling -Infinity float values.", protocol: restXml, code: 200, body: """ -Infinity -Infinity """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { floatValue: "-Infinity", doubleValue: "-Infinity", } }, ]) structure SimpleScalarPropertiesInputOutput { @httpHeader("X-Foo") foo: String, stringValue: String, trueBooleanValue: Boolean, falseBooleanValue: Boolean, byteValue: Byte, shortValue: Short, integerValue: Integer, longValue: Long, floatValue: Float, @xmlName("DoubleDribble") doubleValue: Double, } // This example serializes empty string in the top level XML document. @idempotent @http(uri: "/XmlEmptyStrings", method: "PUT") @tags(["client-only"]) operation XmlEmptyStrings { input: XmlEmptyStringsInputOutput, output: XmlEmptyStringsInputOutput } apply XmlEmptyStrings @httpRequestTests([ { id: "XmlEmptyStrings", documentation: "Serializes xml empty strings", protocol: restXml, method: "PUT", uri: "/XmlEmptyStrings", body: """ """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml", }, params: { emptyString: "", }, appliesTo: "client", } ]) apply XmlEmptyStrings @httpResponseTests([ { id: "XmlEmptyStrings", documentation: "Deserializes xml empty strings", protocol: restXml, code: 200, body: """ """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { emptyString: "" }, appliesTo: "client", }, { id: "XmlEmptySelfClosedStrings", documentation: "Empty self closed string are deserialized as empty string", protocol: restXml, code: 200, body: """ """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { emptyString: "" }, appliesTo: "client", } ]) structure XmlEmptyStringsInputOutput { emptyString: String } /// Blobs are base64 encoded @http(uri: "/XmlBlobs", method: "POST") operation XmlBlobs { input: XmlBlobsInputOutput, output: XmlBlobsInputOutput } apply XmlBlobs @httpRequestTests([ { id: "XmlBlobs", documentation: "Blobs are base64 encoded", protocol: restXml, method: "POST", uri: "/XmlBlobs", body: """ dmFsdWU= """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { data: "value" } } ]) apply XmlBlobs @httpResponseTests([ { id: "XmlBlobs", documentation: "Blobs are base64 encoded", protocol: restXml, code: 200, body: """ dmFsdWU= """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { data: "value" } } ]) /// Blobs are base64 encoded @http(uri: "/XmlEmptyBlobs", method: "POST") @tags(["client-only"]) operation XmlEmptyBlobs { input: XmlBlobsInputOutput, output: XmlBlobsInputOutput } apply XmlEmptyBlobs @httpResponseTests([ { id: "XmlEmptyBlobs", documentation: "Empty blobs are deserialized as empty string", protocol: restXml, code: 200, body: """ """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { data: "" }, appliesTo: "client", }, { id: "XmlEmptySelfClosedBlobs", documentation: "Empty self closed blobs are deserialized as empty string", protocol: restXml, code: 200, body: """ """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { data: "" }, appliesTo: "client", } ]) structure XmlBlobsInputOutput { data: Blob } /// This tests how timestamps are serialized, including using the /// default format of date-time and various @timestampFormat trait /// values. @http(uri: "/XmlTimestamps", method: "POST") operation XmlTimestamps { input: XmlTimestampsInputOutput, output: XmlTimestampsInputOutput } apply XmlTimestamps @httpRequestTests([ { id: "XmlTimestamps", documentation: "Tests how normal timestamps are serialized", protocol: restXml, method: "POST", uri: "/XmlTimestamps", body: """ 2014-04-29T18:30:38Z """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { normal: 1398796238 } }, { id: "XmlTimestampsWithDateTimeFormat", documentation: "Ensures that the timestampFormat of date-time works like normal timestamps", protocol: restXml, method: "POST", uri: "/XmlTimestamps", body: """ 2014-04-29T18:30:38Z """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { dateTime: 1398796238 } }, { id: "XmlTimestampsWithDateTimeOnTargetFormat", documentation: "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", protocol: restXml, method: "POST", uri: "/XmlTimestamps", body: """ 2014-04-29T18:30:38Z """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { dateTimeOnTarget: 1398796238 } }, { id: "XmlTimestampsWithEpochSecondsFormat", documentation: "Ensures that the timestampFormat of epoch-seconds works", protocol: restXml, method: "POST", uri: "/XmlTimestamps", body: """ 1398796238 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { epochSeconds: 1398796238 } }, { id: "XmlTimestampsWithEpochSecondsOnTargetFormat", documentation: "Ensures that the timestampFormat of epoch-seconds on the target shape works", protocol: restXml, method: "POST", uri: "/XmlTimestamps", body: """ 1398796238 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { epochSecondsOnTarget: 1398796238 } }, { id: "XmlTimestampsWithHttpDateFormat", documentation: "Ensures that the timestampFormat of http-date works", protocol: restXml, method: "POST", uri: "/XmlTimestamps", body: """ Tue, 29 Apr 2014 18:30:38 GMT """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { httpDate: 1398796238 } }, { id: "XmlTimestampsWithHttpDateOnTargetFormat", documentation: "Ensures that the timestampFormat of http-date on the target shape works", protocol: restXml, method: "POST", uri: "/XmlTimestamps", body: """ Tue, 29 Apr 2014 18:30:38 GMT """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { httpDateOnTarget: 1398796238 } }, ]) apply XmlTimestamps @httpResponseTests([ { id: "XmlTimestamps", documentation: "Tests how normal timestamps are serialized", protocol: restXml, code: 200, body: """ 2014-04-29T18:30:38Z """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { normal: 1398796238 } }, { id: "XmlTimestampsWithDateTimeFormat", documentation: "Ensures that the timestampFormat of date-time works like normal timestamps", protocol: restXml, code: 200, body: """ 2014-04-29T18:30:38Z """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { dateTime: 1398796238 } }, { id: "XmlTimestampsWithDateTimeOnTargetFormat", documentation: "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", protocol: restXml, code: 200, body: """ 2014-04-29T18:30:38Z """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { dateTimeOnTarget: 1398796238 } }, { id: "XmlTimestampsWithEpochSecondsFormat", documentation: "Ensures that the timestampFormat of epoch-seconds works", protocol: restXml, code: 200, body: """ 1398796238 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { epochSeconds: 1398796238 } }, { id: "XmlTimestampsWithEpochSecondsOnTargetFormat", documentation: "Ensures that the timestampFormat of epoch-seconds on the target shape works", protocol: restXml, code: 200, body: """ 1398796238 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { epochSecondsOnTarget: 1398796238 } }, { id: "XmlTimestampsWithHttpDateFormat", documentation: "Ensures that the timestampFormat of http-date works", protocol: restXml, code: 200, body: """ Tue, 29 Apr 2014 18:30:38 GMT """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { httpDate: 1398796238 } }, { id: "XmlTimestampsWithHttpDateOnTargetFormat", documentation: "Ensures that the timestampFormat of http-date on the target shape works", protocol: restXml, code: 200, body: """ Tue, 29 Apr 2014 18:30:38 GMT """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { httpDateOnTarget: 1398796238 } }, ]) structure XmlTimestampsInputOutput { normal: Timestamp, @timestampFormat("date-time") dateTime: Timestamp, dateTimeOnTarget: DateTime, @timestampFormat("epoch-seconds") epochSeconds: Timestamp, epochSecondsOnTarget: EpochSeconds, @timestampFormat("http-date") httpDate: Timestamp, httpDateOnTarget: HttpDate, } /// This example serializes enums as top level properties, in lists, sets, and maps. @idempotent @http(uri: "/XmlEnums", method: "PUT") operation XmlEnums { input: XmlEnumsInputOutput, output: XmlEnumsInputOutput } apply XmlEnums @httpRequestTests([ { id: "XmlEnums", documentation: "Serializes simple scalar properties", protocol: restXml, method: "PUT", uri: "/XmlEnums", body: """ Foo 0 1 Foo 0 Foo 0 hi Foo zero 0 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { fooEnum1: "Foo", fooEnum2: "0", fooEnum3: "1", fooEnumList: ["Foo", "0"], fooEnumSet: ["Foo", "0"], fooEnumMap: { "hi": "Foo", "zero": "0" } } } ]) apply XmlEnums @httpResponseTests([ { id: "XmlEnums", documentation: "Serializes simple scalar properties", protocol: restXml, code: 200, body: """ Foo 0 1 Foo 0 Foo 0 hi Foo zero 0 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { fooEnum1: "Foo", fooEnum2: "0", fooEnum3: "1", fooEnumList: ["Foo", "0"], fooEnumSet: ["Foo", "0"], fooEnumMap: { "hi": "Foo", "zero": "0" } } } ]) structure XmlEnumsInputOutput { fooEnum1: FooEnum, fooEnum2: FooEnum, fooEnum3: FooEnum, fooEnumList: FooEnumList, fooEnumSet: FooEnumSet, fooEnumMap: FooEnumMap, } /// This example serializes enums as top level properties, in lists, sets, and maps. @idempotent @http(uri: "/XmlIntEnums", method: "PUT") operation XmlIntEnums { input: XmlIntEnumsInputOutput, output: XmlIntEnumsInputOutput } apply XmlIntEnums @httpRequestTests([ { id: "XmlIntEnums", documentation: "Serializes simple scalar properties", protocol: restXml, method: "PUT", uri: "/XmlIntEnums", body: """ 1 2 3 1 2 1 2 a 1 b 2 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { intEnum1: 1, intEnum2: 2, intEnum3: 3, intEnumList: [1, 2], intEnumSet: [1, 2], intEnumMap: { "a": 1, "b": 2 } } } ]) apply XmlIntEnums @httpResponseTests([ { id: "XmlIntEnums", documentation: "Serializes simple scalar properties", protocol: restXml, code: 200, body: """ 1 2 3 1 2 1 2 a 1 b 2 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { intEnum1: 1, intEnum2: 2, intEnum3: 3, intEnumList: [1, 2], intEnumSet: [1, 2], intEnumMap: { "a": 1, "b": 2 } } } ]) structure XmlIntEnumsInputOutput { intEnum1: IntegerEnum, intEnum2: IntegerEnum, intEnum3: IntegerEnum, intEnumList: IntegerEnumList, intEnumSet: IntegerEnumSet, intEnumMap: IntegerEnumMap, } /// Recursive shapes @idempotent @http(uri: "/RecursiveShapes", method: "PUT") operation RecursiveShapes { input: RecursiveShapesInputOutput, output: RecursiveShapesInputOutput } apply RecursiveShapes @httpRequestTests([ { id: "RecursiveShapes", documentation: "Serializes recursive structures", protocol: restXml, method: "PUT", uri: "/RecursiveShapes", body: """ Foo1 Bar1 Foo2 Bar2 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { nested: { foo: "Foo1", nested: { bar: "Bar1", recursiveMember: { foo: "Foo2", nested: { bar: "Bar2" } } } } } } ]) apply RecursiveShapes @httpResponseTests([ { id: "RecursiveShapes", documentation: "Serializes recursive structures", protocol: restXml, code: 200, body: """ Foo1 Bar1 Foo2 Bar2 """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { nested: { foo: "Foo1", nested: { bar: "Bar1", recursiveMember: { foo: "Foo2", nested: { bar: "Bar2" } } } } } } ]) structure RecursiveShapesInputOutput { nested: RecursiveShapesInputOutputNested1 } structure RecursiveShapesInputOutputNested1 { foo: String, nested: RecursiveShapesInputOutputNested2 } structure RecursiveShapesInputOutputNested2 { bar: String, recursiveMember: RecursiveShapesInputOutputNested1, } // XML namespace @http(uri: "/XmlNamespaces", method: "POST") operation XmlNamespaces { input: XmlNamespacesInputOutput, output: XmlNamespacesInputOutput } apply XmlNamespaces @httpRequestTests([ { id: "XmlNamespaces", documentation: "Serializes XML namespaces", protocol: restXml, method: "POST", uri: "/XmlNamespaces", body: """ Foo Bar Baz """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { nested: { foo: "Foo", values: [ "Bar", "Baz" ] } } } ]) apply XmlNamespaces @httpResponseTests([ { id: "XmlNamespaces", documentation: "Serializes XML namespaces", protocol: restXml, code: 200, body: """ Foo Bar Baz """, bodyMediaType: "application/xml", headers: { "Content-Type": "application/xml" }, params: { nested: { foo: "Foo", values: [ "Bar", "Baz" ] } } } ]) @xmlNamespace(uri: "http://foo.com") structure XmlNamespacesInputOutput { nested: XmlNamespaceNested } // Ignored since it's not at the top-level @xmlNamespace(uri: "http://foo.com") structure XmlNamespaceNested { @xmlNamespace(uri: "http://baz.com", prefix: "baz") foo: String, @xmlNamespace(uri: "http://qux.com") values: XmlNamespacedList } list XmlNamespacedList { @xmlNamespace(uri: "http://bux.com") member: String, }