diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/HttpProtocolTestGenerator.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/HttpProtocolTestGenerator.java index 518fb0643d6..7d24d96fbbc 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/HttpProtocolTestGenerator.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/HttpProtocolTestGenerator.java @@ -278,53 +278,42 @@ private void writeRequestBodyAssertions(OperationShape operation, HttpRequestTes writer.write("expect(r.body).toBeDefined();"); // Otherwise load a media type specific comparator and do a comparison. - String mediaType = testCase.getBodyMediaType().orElse(null); - - // Fast check if we have an undescribed or plain text body. - if (mediaType == null || mediaType.equals("text/plain")) { - // Handle converting to the right comparison format for blob payloads. - HttpBindingIndex httpBindingIndex = HttpBindingIndex.of(model); - List payloadBindings = httpBindingIndex.getRequestBindings(operation, Location.PAYLOAD); - if (!payloadBindings.isEmpty() && hasBlobBinding(payloadBindings)) { - writer.write("expect(r.body).toMatchObject(Uint8Array.from($S, c => c.charCodeAt(0)));", body); - } else { - writer.write("expect(r.body).toBe($S);", body); - } - return; - } - registerBodyComparatorStub(mediaType); + String mediaType = testCase.getBodyMediaType().orElse("UNKNOWN"); + String comparatorInvoke = registerBodyComparatorStub(mediaType); // Handle escaping strings with quotes inside them. writer.write("const bodyString = `$L`;", body.replace("\"", "\\\"")); - writer.write("const unequalParts: any = compareEquivalentBodies(bodyString, r.body.toString());"); + writer.write("const unequalParts: any = $L;", comparatorInvoke); writer.write("expect(unequalParts).toBeUndefined();"); }); } - private boolean hasBlobBinding(List payloadBindings) { - // Can only have one payload binding at a time. - return model.expectShape(payloadBindings.get(0).getMember().getTarget()).isBlobShape(); - } - - private void registerBodyComparatorStub(String mediaType) { + private String registerBodyComparatorStub(String mediaType) { // Load an additional stub to handle body comparisons for the // set of bodyMediaType values we know of. switch (mediaType) { case "application/x-www-form-urlencoded": additionalStubs.add("protocol-test-form-urlencoded-stub.ts"); - break; + return "compareEquivalentFormUrlencodedBodies(bodyString, r.body.toString())"; case "application/json": additionalStubs.add("protocol-test-json-stub.ts"); - break; + return "compareEquivalentJsonBodies(bodyString, r.body.toString())"; case "application/xml": writer.addDependency(TypeScriptDependency.XML_PARSER); writer.addImport("parse", "xmlParse", "fast-xml-parser"); additionalStubs.add("protocol-test-xml-stub.ts"); - break; + return "compareEquivalentXmlBodies(bodyString, r.body.toString())"; + case "application/octet-stream": + additionalStubs.add("protocol-test-octet-stream-stub.ts"); + return "compareEquivalentOctetStreamBodies(client.config, bodyString, r.body)"; + case "text/plain": + additionalStubs.add("protocol-test-text-stub.ts"); + return "compareEquivalentTextBodies(bodyString, r.body)"; default: LOGGER.warning("Unable to compare bodies with unknown media type `" + mediaType + "`, defaulting to direct comparison."); additionalStubs.add("protocol-test-unknown-type-stub.ts"); + return "compareEquivalentUnknownTypeBodies(client.config, bodyString, r.body)"; } } diff --git a/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-form-urlencoded-stub.ts b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-form-urlencoded-stub.ts index e271bd84f14..ef67aff33a8 100644 --- a/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-form-urlencoded-stub.ts +++ b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-form-urlencoded-stub.ts @@ -2,7 +2,7 @@ * Returns a map of key names that were un-equal to value objects showing the * discrepancies between the components. */ -const compareEquivalentBodies = (expectedBody: string, generatedBody: string): Object => { +const compareEquivalentFormUrlencodedBodies = (expectedBody: string, generatedBody: string): Object => { const fromEntries = (components: string[][]): { [key: string]: string } => { const parts: { [key: string]: string } = {}; diff --git a/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-json-stub.ts b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-json-stub.ts index 24617c7a750..49e640eb91d 100644 --- a/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-json-stub.ts +++ b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-json-stub.ts @@ -2,7 +2,7 @@ * Returns a map of key names that were un-equal to value objects showing the * discrepancies between the components. */ -const compareEquivalentBodies = (expectedBody: string, generatedBody: string): Object => { +const compareEquivalentJsonBodies = (expectedBody: string, generatedBody: string): Object => { const expectedParts = JSON.parse(expectedBody); const generatedParts = JSON.parse(generatedBody); diff --git a/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-octet-stream-stub.ts b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-octet-stream-stub.ts new file mode 100644 index 00000000000..2d99a5abae1 --- /dev/null +++ b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-octet-stream-stub.ts @@ -0,0 +1,14 @@ +/** + * Returns a map of key names that were un-equal to value objects showing the + * discrepancies between the components. + */ +const compareEquivalentOctetStreamBodies = ( + config: any, + expectedBody: string, + generatedBody: Uint8Array +): Object => { + const expectedParts = {Value: expectedBody}; + const generatedParts = {Value: config.utf8Encoder(generatedBody)}; + + return compareParts(expectedParts, generatedParts); +} diff --git a/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-text-stub.ts b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-text-stub.ts new file mode 100644 index 00000000000..ede3b37e23e --- /dev/null +++ b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-text-stub.ts @@ -0,0 +1,10 @@ +/** + * Returns a map of key names that were un-equal to value objects showing the + * discrepancies between the components. + */ +const compareEquivalentTextBodies = (expectedBody: string, generatedBody: string): Object => { + const expectedParts = {Value: expectedBody}; + const generatedParts = {Value: generatedBody}; + + return compareParts(expectedParts, generatedParts); +} diff --git a/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-unknown-type-stub.ts b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-unknown-type-stub.ts index a371b1e4c51..69afea79e4e 100644 --- a/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-unknown-type-stub.ts +++ b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-unknown-type-stub.ts @@ -2,9 +2,15 @@ * Returns a map of key names that were un-equal to value objects showing the * discrepancies between the components. */ -const compareEquivalentBodies = (expectedBody: string, generatedBody: string): Object => { +const compareEquivalentUnknownTypeBodies = ( + config: any, + expectedBody: string, + generatedBody: string | Uint8Array +): Object => { const expectedParts = {Value: expectedBody}; - const generatedParts = {Value: generatedBody}; + const generatedParts = { + Value: generatedBody instanceof Uint8Array ? config.utf8Encoder(generatedBody) : generatedBody + }; return compareParts(expectedParts, generatedParts); } diff --git a/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-xml-stub.ts b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-xml-stub.ts index df212226b9e..568d1eb04ad 100644 --- a/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-xml-stub.ts +++ b/smithy-typescript-codegen/src/main/resources/software/amazon/smithy/typescript/codegen/protocol-test-xml-stub.ts @@ -2,7 +2,7 @@ * Returns a map of key names that were un-equal to value objects showing the * discrepancies between the components. */ -const compareEquivalentBodies = (expectedBody: string, generatedBody: string): Object => { +const compareEquivalentXmlBodies = (expectedBody: string, generatedBody: string): Object => { const decodeEscapedXml = (str: string) => { return str .replace(/&/g, "&")