Skip to content

Commit 7e88575

Browse files
committed
PR comments
1 parent b4cd801 commit 7e88575

File tree

6 files changed

+143
-43
lines changed

6 files changed

+143
-43
lines changed

Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Extensions/ApiGatewayResponseExtensions.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public static void ToHttpResponse(this APIGatewayProxyResponse apiResponse, Http
2626
response.Clear();
2727

2828
SetResponseHeaders(response, apiResponse.Headers, emulatorMode, apiResponse.MultiValueHeaders);
29-
SetResponseBody(response, apiResponse.Body, apiResponse.IsBase64Encoded, emulatorMode);
29+
SetResponseBody(response, apiResponse.Body, apiResponse.IsBase64Encoded);
3030
SetContentTypeAndStatusCodeV1(response, apiResponse.Headers, apiResponse.MultiValueHeaders, apiResponse.StatusCode, emulatorMode);
3131
}
3232

@@ -41,7 +41,7 @@ public static void ToHttpResponse(this APIGatewayHttpApiV2ProxyResponse apiRespo
4141
response.Clear();
4242

4343
SetResponseHeaders(response, apiResponse.Headers, ApiGatewayEmulatorMode.HttpV2);
44-
SetResponseBody(response, apiResponse.Body, apiResponse.IsBase64Encoded, ApiGatewayEmulatorMode.HttpV2);
44+
SetResponseBody(response, apiResponse.Body, apiResponse.IsBase64Encoded);
4545
SetContentTypeAndStatusCodeV2(response, apiResponse.Headers, apiResponse.StatusCode);
4646
}
4747

@@ -151,13 +151,12 @@ private static string GenerateRequestId()
151151
/// <param name="response">The <see cref="HttpResponse"/> to set the body on.</param>
152152
/// <param name="body">The body content.</param>
153153
/// <param name="isBase64Encoded">Whether the body is Base64 encoded.</param>
154-
/// <param name="apiGatewayEmulator">The <see cref="ApiGatewayEmulatorMode"/> being used.</param>
155-
private static void SetResponseBody(HttpResponse response, string? body, bool isBase64Encoded, ApiGatewayEmulatorMode apiGatewayEmulator)
154+
private static void SetResponseBody(HttpResponse response, string? body, bool isBase64Encoded)
156155
{
157156
if (!string.IsNullOrEmpty(body))
158157
{
159158
byte[] bodyBytes;
160-
if (isBase64Encoded && ApiGatewayEmulatorMode.Rest != apiGatewayEmulator) // rest api gateway doesnt automatically decode the response
159+
if (isBase64Encoded)
161160
{
162161
bodyBytes = Convert.FromBase64String(body);
163162
}

Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/ApiGatewayIntegrationTestFixture.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ public class ApiGatewayIntegrationTestFixture : IAsyncLifetime
2424
public string HttpApiV1Url { get; private set; }
2525
public string HttpApiV2Url { get; private set; }
2626
public string ReturnRawRequestBodyHttpApiV2Url { get; private set; }
27+
public string BinaryMediaRestApiId { get; private set; }
28+
public string BinaryMediaRestApiUrl { get; private set; }
29+
2730

2831
public ApiGatewayIntegrationTestFixture()
2932
{
@@ -43,6 +46,8 @@ public ApiGatewayIntegrationTestFixture()
4346
HttpApiV1Url = string.Empty;
4447
HttpApiV2Url = string.Empty;
4548
ReturnRawRequestBodyHttpApiV2Url = string.Empty;
49+
BinaryMediaRestApiId = string.Empty;
50+
BinaryMediaRestApiUrl = string.Empty;
4651
}
4752

4853
public async Task InitializeAsync()
@@ -105,6 +110,9 @@ private async Task RetrieveStackOutputs()
105110

106111
ReturnRawRequestBodyV2Id = await CloudFormationHelper.GetOutputValueAsync(StackName, "ReturnRawRequestBodyHttpApiId");
107112
ReturnRawRequestBodyHttpApiV2Url = await CloudFormationHelper.GetOutputValueAsync(StackName, "ReturnRawRequestBodyHttpApiUrl");
113+
114+
BinaryMediaRestApiId = await CloudFormationHelper.GetOutputValueAsync(StackName, "BinaryMediaRestApiId");
115+
BinaryMediaRestApiUrl = await CloudFormationHelper.GetOutputValueAsync(StackName, "BinaryMediaRestApiUrl");
108116
}
109117

110118
private async Task WaitForApisAvailability()
@@ -113,6 +121,7 @@ private async Task WaitForApisAvailability()
113121
await ApiGatewayHelper.WaitForApiAvailability(HttpApiV1Id, HttpApiV1Url, true);
114122
await ApiGatewayHelper.WaitForApiAvailability(HttpApiV2Id, HttpApiV2Url, true);
115123
await ApiGatewayHelper.WaitForApiAvailability(ReturnRawRequestBodyV2Id, ReturnRawRequestBodyHttpApiV2Url, true);
124+
await ApiGatewayHelper.WaitForApiAvailability(BinaryMediaRestApiId, BinaryMediaRestApiUrl, false);
116125
}
117126

118127
public async Task DisposeAsync()
Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@
55
using Microsoft.AspNetCore.Http;
66
using System.Text.Json;
77
using Amazon.Lambda.TestTool.Extensions;
8+
using Amazon.Lambda.TestTool.Models;
9+
using System.Text;
810

911
namespace Amazon.Lambda.TestTool.IntegrationTests
1012
{
1113
[Collection("ApiGateway Integration Tests")]
12-
public class ApiGatewayResponseExtensionsTestsManual
14+
public class ApiGatewayResponseExtensionsAdditionalTests
1315
{
1416
private readonly ApiGatewayIntegrationTestFixture _fixture;
1517
private readonly HttpClient _httpClient;
1618

17-
public ApiGatewayResponseExtensionsTestsManual(ApiGatewayIntegrationTestFixture fixture)
19+
public ApiGatewayResponseExtensionsAdditionalTests(ApiGatewayIntegrationTestFixture fixture)
1820
{
1921
_fixture = fixture;
2022
_httpClient = new HttpClient();
@@ -62,5 +64,45 @@ public async Task V2_SetsContentTypeApplicationJsonWhenNoStatusProvidedAndDoesnt
6264
var responsePayload = JsonSerializer.Deserialize<Dictionary<string, object>>(content);
6365
Assert.Equal("value", responsePayload?["key"].ToString());
6466
}
67+
68+
69+
[Fact]
70+
public async Task ToHttpResponse_RestAPIGatewayV1DecodesBase64()
71+
{
72+
var testResponse = new APIGatewayProxyResponse
73+
{
74+
StatusCode = 200,
75+
Body = Convert.ToBase64String(Encoding.UTF8.GetBytes("test")),
76+
IsBase64Encoded = true
77+
};
78+
79+
var httpContext = new DefaultHttpContext();
80+
testResponse.ToHttpResponse(httpContext, ApiGatewayEmulatorMode.Rest);
81+
var actualResponse = await _httpClient.PostAsync(_fixture.BinaryMediaRestApiUrl, new StringContent(JsonSerializer.Serialize(testResponse)));
82+
await _fixture.ApiGatewayTestHelper.AssertResponsesEqual(actualResponse, httpContext.Response);
83+
Assert.Equal(200, (int)actualResponse.StatusCode);
84+
var content = await actualResponse.Content.ReadAsStringAsync();
85+
Assert.Equal("test", content);
86+
}
87+
88+
[Fact]
89+
public async Task ToHttpResponse_HttpV1APIGatewayV1DecodesBase64()
90+
{
91+
var testResponse = new APIGatewayProxyResponse
92+
{
93+
StatusCode = 200,
94+
Body = Convert.ToBase64String(Encoding.UTF8.GetBytes("test")),
95+
IsBase64Encoded = true
96+
};
97+
98+
var httpContext = new DefaultHttpContext();
99+
testResponse.ToHttpResponse(httpContext, ApiGatewayEmulatorMode.HttpV1);
100+
var actualResponse = await _httpClient.PostAsync(_fixture.HttpApiV1Url, new StringContent(JsonSerializer.Serialize(testResponse)));
101+
102+
await _fixture.ApiGatewayTestHelper.AssertResponsesEqual(actualResponse, httpContext.Response);
103+
Assert.Equal(200, (int)actualResponse.StatusCode);
104+
var content = await actualResponse.Content.ReadAsStringAsync();
105+
Assert.Equal("test", content);
106+
}
65107
}
66108
}

Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.IntegrationTests/cloudformation-template-apigateway.yaml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ Resources:
1616
};
1717
Runtime: nodejs20.x
1818

19+
BinaryLambdaFunction:
20+
Type: 'AWS::Lambda::Function'
21+
Properties:
22+
FunctionName: !Sub '${AWS::StackName}-BinaryFunction'
23+
Handler: index.handler
24+
Role: !GetAtt LambdaExecutionRole.Arn
25+
Code:
26+
ZipFile: |
27+
exports.handler = async (event) => {
28+
const decodedBody = atob(event.body);
29+
const parsedBody = JSON.parse(decodedBody.toString('utf8'));
30+
return parsedBody;
31+
};
32+
Runtime: nodejs20.x
33+
1934
ReturnRawRequestBodyLambdaFunction:
2035
Type: 'AWS::Lambda::Function'
2136
Properties:
@@ -199,6 +214,47 @@ Resources:
199214
Principal: apigateway.amazonaws.com
200215
SourceArn: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ReturnRawRequestBodyHttpApi}/*'
201216

217+
BinaryMediaRestApi:
218+
Type: 'AWS::ApiGateway::RestApi'
219+
Properties:
220+
Name: !Sub '${AWS::StackName}-BinaryMediaRestAPI'
221+
BinaryMediaTypes:
222+
- '*/*'
223+
224+
BinaryMediaRestApiResource:
225+
Type: 'AWS::ApiGateway::Resource'
226+
Properties:
227+
ParentId: !GetAtt BinaryMediaRestApi.RootResourceId
228+
PathPart: 'test'
229+
RestApiId: !Ref BinaryMediaRestApi
230+
231+
BinaryMediaRestApiMethod:
232+
Type: 'AWS::ApiGateway::Method'
233+
Properties:
234+
HttpMethod: POST
235+
ResourceId: !Ref BinaryMediaRestApiResource
236+
RestApiId: !Ref BinaryMediaRestApi
237+
AuthorizationType: NONE
238+
Integration:
239+
Type: AWS_PROXY
240+
IntegrationHttpMethod: POST
241+
Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${BinaryLambdaFunction.Arn}/invocations'
242+
243+
BinaryMediaRestApiDeployment:
244+
Type: 'AWS::ApiGateway::Deployment'
245+
DependsOn: BinaryMediaRestApiMethod
246+
Properties:
247+
RestApiId: !Ref BinaryMediaRestApi
248+
StageName: 'test'
249+
250+
LambdaPermissionBinaryMediaRestApi:
251+
Type: 'AWS::Lambda::Permission'
252+
Properties:
253+
Action: 'lambda:InvokeFunction'
254+
FunctionName: !GetAtt BinaryLambdaFunction.Arn
255+
Principal: apigateway.amazonaws.com
256+
SourceArn: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${BinaryMediaRestApi}/*'
257+
202258
Outputs:
203259
RestApiId:
204260
Description: 'ID of the REST API'
@@ -231,3 +287,11 @@ Outputs:
231287
ReturnRawRequestBodyHttpApiUrl:
232288
Description: 'URL of the JSON Inference HTTP API'
233289
Value: !Sub 'https://${ReturnRawRequestBodyHttpApi}.execute-api.${AWS::Region}.amazonaws.com/'
290+
291+
BinaryMediaRestApiId:
292+
Description: 'ID of the Binary Media REST API'
293+
Value: !Ref BinaryMediaRestApi
294+
295+
BinaryMediaRestApiUrl:
296+
Description: 'URL of the Binary Media REST API'
297+
Value: !Sub 'https://${BinaryMediaRestApi}.execute-api.${AWS::Region}.amazonaws.com/test/test'

Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.UnitTests/Extensions/ApiGatewayResponseExtensionsTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
using System.Text;
45
using Amazon.Lambda.APIGatewayEvents;
56
using Amazon.Lambda.TestTool.Extensions;
67
using Amazon.Lambda.TestTool.Models;
@@ -71,5 +72,26 @@ public void ToHttpResponse_APIGatewayHttpApiV2ProxyResponse_InfersResponseFormat
7172
var bodyContent = reader.ReadToEnd();
7273
Assert.Equal(jsonBody, bodyContent);
7374
}
75+
76+
[Theory]
77+
[InlineData(ApiGatewayEmulatorMode.HttpV1)]
78+
[InlineData(ApiGatewayEmulatorMode.Rest)]
79+
public void ToHttpResponse_APIGatewayV1DecodesBase64(ApiGatewayEmulatorMode emulatorMode)
80+
{
81+
var apiResponse = new APIGatewayProxyResponse
82+
{
83+
StatusCode = 200,
84+
Body = Convert.ToBase64String(Encoding.UTF8.GetBytes("test")),
85+
IsBase64Encoded = true
86+
};
87+
88+
var httpContext = new DefaultHttpContext();
89+
apiResponse.ToHttpResponse(httpContext, emulatorMode);
90+
91+
httpContext.Response.Body.Seek(0, SeekOrigin.Begin);
92+
using var reader = new StreamReader(httpContext.Response.Body);
93+
var bodyContent = reader.ReadToEnd();
94+
Assert.Equal("test", bodyContent);
95+
}
7496
}
7597
}

Tools/LambdaTestTool-v2/tests/Amazon.Lambda.TestTool.UnitTests/Extensions/ApiGatewayResponseTestCases.cs

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -145,42 +145,6 @@ public static IEnumerable<object[]> V1TestCases()
145145
}
146146
};
147147

148-
yield return new object[]
149-
{
150-
"V1_SetsBodyBase64",
151-
new ApiGatewayResponseTestCase
152-
{
153-
Response = new APIGatewayProxyResponse
154-
{
155-
StatusCode = 200,
156-
Body = Convert.ToBase64String(Encoding.UTF8.GetBytes("{\"message\":\"Hello, World!\"}")),
157-
IsBase64Encoded = true
158-
},
159-
Assertions = (response, emulatormode) =>
160-
{
161-
if (emulatormode == ApiGatewayEmulatorMode.Rest)
162-
{
163-
164-
} else
165-
{
166-
Assert.Equal("{\"message\":\"Hello, World!\"}", ReadResponseBody(response));
167-
}
168-
},
169-
IntegrationAssertions = async (response, emulatorMode) =>
170-
{
171-
var content = await response.Content.ReadAsStringAsync();
172-
if (emulatorMode == ApiGatewayEmulatorMode.Rest)
173-
{
174-
Assert.Equal(Convert.ToBase64String(Encoding.UTF8.GetBytes("{\"message\":\"Hello, World!\"}")), content); // rest doesnt decode
175-
} else
176-
{
177-
Assert.Equal("{\"message\":\"Hello, World!\"}", content);
178-
}
179-
await Task.CompletedTask;
180-
}
181-
}
182-
};
183-
184148
yield return new object[]
185149
{
186150
"V1_DefaultsToCorrectContentTYpe",

0 commit comments

Comments
 (0)