From bfb9de2337784e0e370825d44ec39b0dd776ac5d Mon Sep 17 00:00:00 2001 From: Kevin Stich Date: Wed, 5 Jun 2024 10:59:42 -0700 Subject: [PATCH] Add bodyMediaType to malformed request tests This commit adds the bodyMediaType field to request definitions in httpMalformedRequestsTests. Specifying the body media type allows tests to specify protocols that use binary-based serialization formats, like Smithy RPCv2 CBOR, as their bodies must be base64-encoded in models. --- .../HttpMalformedRequestDefinition.java | 16 ++++++++++++++++ .../META-INF/smithy/smithy.test.smithy | 6 ++++++ .../all-malformed-request-features.smithy | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/smithy-protocol-test-traits/src/main/java/software/amazon/smithy/protocoltests/traits/HttpMalformedRequestDefinition.java b/smithy-protocol-test-traits/src/main/java/software/amazon/smithy/protocoltests/traits/HttpMalformedRequestDefinition.java index 9bace721d23..b86bdb06369 100644 --- a/smithy-protocol-test-traits/src/main/java/software/amazon/smithy/protocoltests/traits/HttpMalformedRequestDefinition.java +++ b/smithy-protocol-test-traits/src/main/java/software/amazon/smithy/protocoltests/traits/HttpMalformedRequestDefinition.java @@ -38,6 +38,7 @@ public final class HttpMalformedRequestDefinition implements ToNode, ToSmithyBuilder { private static final String BODY = "body"; + private static final String BODY_MEDIA_TYPE = "bodyMediaType"; private static final String HEADERS = "headers"; private static final String HOST = "host"; private static final String METHOD = "method"; @@ -45,6 +46,7 @@ public final class HttpMalformedRequestDefinition implements ToNode, ToSmithyBui private static final String URI = "uri"; private final String body; + private final String bodyMediaType; private final Map headers; private final String host; private final String method; @@ -53,6 +55,7 @@ public final class HttpMalformedRequestDefinition implements ToNode, ToSmithyBui private HttpMalformedRequestDefinition(Builder builder) { body = builder.body; + bodyMediaType = builder.bodyMediaType; host = builder.host; headers = MapUtils.copyOf(builder.headers); method = SmithyBuilder.requiredState(METHOD, builder.method); @@ -64,6 +67,10 @@ public Optional getBody() { return Optional.ofNullable(body); } + public Optional getBodyMediaType() { + return Optional.ofNullable(bodyMediaType); + } + public Map getHeaders() { return headers; } @@ -93,6 +100,7 @@ public static HttpMalformedRequestDefinition fromNode(Node node) { HttpMalformedRequestDefinition.Builder builder = builder(); ObjectNode o = node.expectObjectNode(); o.getStringMember(BODY).map(StringNode::getValue).ifPresent(builder::body); + o.getStringMember(BODY_MEDIA_TYPE).map(StringNode::getValue).ifPresent(builder::bodyMediaType); o.getObjectMember(HEADERS).ifPresent(headers -> { headers.getStringMap().forEach((k, v) -> { builder.putHeader(k, v.expectStringNode().getValue()); @@ -111,6 +119,7 @@ public static HttpMalformedRequestDefinition fromNode(Node node) { public Node toNode() { return Node.objectNodeBuilder() .withOptionalMember(BODY, getBody().map(Node::from)) + .withOptionalMember(BODY_MEDIA_TYPE, getBodyMediaType().map(Node::from)) .withOptionalMember(HEADERS, headers.isEmpty() ? Optional.empty() : Optional.of(ObjectNode.fromStringMap(getHeaders()))) .withOptionalMember(HOST, getHost().map(StringNode::from)) @@ -128,6 +137,7 @@ public Builder toBuilder() { .method(getMethod()) .queryParams(getQueryParams()); getBody().ifPresent(builder::body); + getBodyMediaType().ifPresent(builder::bodyMediaType); getHost().ifPresent(builder::host); getUri().ifPresent(builder::uri); return builder; @@ -143,6 +153,7 @@ public static Builder builder() { public static final class Builder implements SmithyBuilder { private String body; + private String bodyMediaType; private String host; private final Map headers = new HashMap<>(); private String method; @@ -156,6 +167,11 @@ public Builder body(String body) { return this; } + public Builder bodyMediaType(String bodyMediaType) { + this.bodyMediaType = bodyMediaType; + return this; + } + public Builder headers(Map headers) { this.headers.clear(); this.headers.putAll(headers); diff --git a/smithy-protocol-test-traits/src/main/resources/META-INF/smithy/smithy.test.smithy b/smithy-protocol-test-traits/src/main/resources/META-INF/smithy/smithy.test.smithy index 51c97b38f37..185cdb4b146 100644 --- a/smithy-protocol-test-traits/src/main/resources/META-INF/smithy/smithy.test.smithy +++ b/smithy-protocol-test-traits/src/main/resources/META-INF/smithy/smithy.test.smithy @@ -359,6 +359,12 @@ structure HttpMalformedRequestDefinition { /// The HTTP message body to include in the request body: String, + + /// The media type of the `body`. + /// + /// This is used to help test runners to parse and validate the expected + /// data against generated data. + bodyMediaType: String } @private diff --git a/smithy-protocol-test-traits/src/test/resources/software/amazon/smithy/protocoltests/traits/errorfiles/all-malformed-request-features.smithy b/smithy-protocol-test-traits/src/test/resources/software/amazon/smithy/protocoltests/traits/errorfiles/all-malformed-request-features.smithy index d9f042a0bb3..24a193e0d50 100644 --- a/smithy-protocol-test-traits/src/test/resources/software/amazon/smithy/protocoltests/traits/errorfiles/all-malformed-request-features.smithy +++ b/smithy-protocol-test-traits/src/test/resources/software/amazon/smithy/protocoltests/traits/errorfiles/all-malformed-request-features.smithy @@ -101,6 +101,25 @@ structure testProtocol {} "bar" : ["d", "e", "f"] } } + { + id: "noResponseBodyAssertionWithMediaType" + documentation: "Testing..." + protocol: testProtocol + request: { + body: "Zm9vCg==" + bodyMediaType: "application/cbor" + headers: {"X-Foo": "baz"} + host: "example.com" + method: "POST" + uri: "/" + queryParams: ["foo=baz"] + }, + response: { + code: 400 + headers: {"X-Foo": "baz"} + }, + tags: ["foo", "bar"] + }, ]) operation SayHello { input: SayHelloInput,