Skip to content

Commit 5f90129

Browse files
Add integration test for binary content for rest api for apigatewayrequest object (#1929)
1 parent 1d5ce54 commit 5f90129

File tree

5 files changed

+86
-29
lines changed

5 files changed

+86
-29
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
namespace Amazon.Lambda.TestTool.Extensions;
55

6-
using System.Text;
76
using System.Web;
87
using Amazon.Lambda.APIGatewayEvents;
98
using Amazon.Lambda.TestTool.Models;
@@ -152,6 +151,13 @@ public static async Task<APIGatewayProxyRequest> ToApiGatewayRequest(
152151
multiValueHeaders["content-type"] = ["text/plain; charset=utf-8"];
153152
}
154153

154+
155+
if (HttpRequestUtility.IsBinaryContent(request.ContentType) && emulatorMode == ApiGatewayEmulatorMode.Rest) // Rest mode with binary content never sends content length
156+
{
157+
headers.Remove("content-length");
158+
multiValueHeaders.Remove("content-length");
159+
}
160+
155161
// This is the decoded value
156162
var path = request.Path.Value;
157163

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ public class ApiGatewayIntegrationTestFixture : IAsyncLifetime
4242
public string ReturnFullEventHttpApiV2Url { get; private set; }
4343

4444
// ReturnDecodedParseBin
45-
public string ReturnDecodedParseBinRestApiId { get; private set; }
46-
public string ReturnDecodedParseBinRestApiUrl { get; private set; }
45+
public string BinaryMediaTypeRestApiId { get; private set; }
46+
public string BinaryMediaTypeRestApiUrl { get; private set; }
4747

4848
// Lambda Function ARNs
4949
public string ParseAndReturnBodyLambdaFunctionArn { get; private set; }
@@ -86,9 +86,9 @@ public ApiGatewayIntegrationTestFixture()
8686
ReturnFullEventHttpApiV1Url = string.Empty;
8787
ReturnFullEventHttpApiV2Url = string.Empty;
8888

89-
// ReturnDecodedParseBin
90-
ReturnDecodedParseBinRestApiId = string.Empty;
91-
ReturnDecodedParseBinRestApiUrl = string.Empty;
89+
// BinaryMediaTypeRestApiId
90+
BinaryMediaTypeRestApiId = string.Empty;
91+
BinaryMediaTypeRestApiUrl = string.Empty;
9292

9393
// Lambda Function ARNs
9494
ParseAndReturnBodyLambdaFunctionArn = string.Empty;
@@ -170,8 +170,8 @@ private async Task RetrieveStackOutputs()
170170
ReturnFullEventHttpApiV2Url = await CloudFormationHelper.GetOutputValueAsync(StackName, "ReturnFullEventHttpApiV2Url");
171171

172172
// ReturnDecodedParseBin
173-
ReturnDecodedParseBinRestApiId = await CloudFormationHelper.GetOutputValueAsync(StackName, "ReturnDecodedParseBinRestApiId");
174-
ReturnDecodedParseBinRestApiUrl = await CloudFormationHelper.GetOutputValueAsync(StackName, "ReturnDecodedParseBinRestApiUrl");
173+
BinaryMediaTypeRestApiId = await CloudFormationHelper.GetOutputValueAsync(StackName, "BinaryMediaTypeRestApiId");
174+
BinaryMediaTypeRestApiUrl = await CloudFormationHelper.GetOutputValueAsync(StackName, "BinaryMediaTypeRestApiUrl");
175175

176176
// Lambda Function ARNs
177177
ParseAndReturnBodyLambdaFunctionArn = await CloudFormationHelper.GetOutputValueAsync(StackName, "ParseAndReturnBodyLambdaFunctionArn");
@@ -196,7 +196,7 @@ private async Task WaitForApisAvailability()
196196
await ApiGatewayHelper.WaitForApiAvailability(ReturnFullEventHttpApiV1Id, ReturnFullEventHttpApiV1Url, true);
197197
await ApiGatewayHelper.WaitForApiAvailability(ReturnFullEventHttpApiV2Id, ReturnFullEventHttpApiV2Url, true);
198198

199-
await ApiGatewayHelper.WaitForApiAvailability(ReturnDecodedParseBinRestApiId, ReturnDecodedParseBinRestApiUrl, false);
199+
await ApiGatewayHelper.WaitForApiAvailability(BinaryMediaTypeRestApiId, BinaryMediaTypeRestApiUrl, false);
200200

201201
}
202202

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public async Task ToHttpResponse_RestAPIGatewayV1DecodesBase64()
5454

5555
var httpContext = new DefaultHttpContext();
5656
testResponse.ToHttpResponse(httpContext, ApiGatewayEmulatorMode.Rest);
57-
var actualResponse = await _httpClient.PostAsync(_fixture.ReturnDecodedParseBinRestApiUrl, new StringContent(JsonSerializer.Serialize(testResponse)));
57+
var actualResponse = await _httpClient.PostAsync(_fixture.BinaryMediaTypeRestApiUrl, new StringContent(JsonSerializer.Serialize(testResponse)));
5858
await _fixture.ApiGatewayTestHelper.AssertResponsesEqual(actualResponse, httpContext.Response);
5959
Assert.Equal(200, (int)actualResponse.StatusCode);
6060
var content = await actualResponse.Content.ReadAsStringAsync();

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,49 @@ await RunApiGatewayTest<APIGatewayProxyRequest>(
101101
);
102102
}
103103

104+
[Fact]
105+
public async Task BinaryContentRest()
106+
{
107+
var httpContext = CreateHttpContext("POST", "/test4/api/users/123/avatar",
108+
new Dictionary<string, StringValues> { { "Content-Type", "application/octet-stream" } },
109+
body: new byte[] { 1, 2, 3, 4, 5 });
110+
111+
var config = new ApiGatewayRouteConfig
112+
{
113+
LambdaResourceName = "UploadAvatarFunction",
114+
Endpoint = "/test4/api/users/{userId}/avatar",
115+
HttpMethod = "POST",
116+
Path = "/test4/api/users/{userId}/avatar"
117+
};
118+
119+
var testCase = new HttpContextTestCase
120+
{
121+
HttpContext = httpContext,
122+
ApiGatewayRouteConfig = config,
123+
Assertions = (actualRequest, emulatorMode) =>
124+
{
125+
var typedRequest = (APIGatewayProxyRequest)actualRequest;
126+
Assert.True(typedRequest.IsBase64Encoded);
127+
Assert.Equal(Convert.ToBase64String(new byte[] { 1, 2, 3, 4, 5 }), typedRequest.Body);
128+
Assert.Equal("123", typedRequest.PathParameters["userId"]);
129+
Assert.Equal("/test4/api/users/{userId}/avatar", typedRequest.Resource);
130+
Assert.Equal("POST", typedRequest.HttpMethod);
131+
}
132+
};
133+
134+
var route = testCase.ApiGatewayRouteConfig?.Path ?? "/test";
135+
var routeKey = testCase.ApiGatewayRouteConfig?.HttpMethod ?? "POST";
136+
await _fixture.ApiGatewayHelper.AddRouteToRestApi(_fixture.BinaryMediaTypeRestApiId, _fixture.ReturnFullEventLambdaFunctionArn, route, routeKey);
137+
138+
await RunApiGatewayTest<APIGatewayProxyRequest>(
139+
testCase,
140+
_fixture.BinaryMediaTypeRestApiUrl,
141+
_fixture.BinaryMediaTypeRestApiId,
142+
async (context, cfg) => await context.ToApiGatewayRequest(cfg, ApiGatewayEmulatorMode.Rest),
143+
ApiGatewayEmulatorMode.Rest
144+
);
145+
}
146+
104147
private async Task RunApiGatewayTest<T>(HttpContextTestCase testCase, string apiUrl, string apiId, Func<HttpContext, ApiGatewayRouteConfig, Task<T>> toApiGatewayRequest, ApiGatewayEmulatorMode emulatorMode)
105148
where T : class
106149
{

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

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -441,49 +441,57 @@ Resources:
441441
Principal: apigateway.amazonaws.com
442442
SourceArn: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ReturnFullEventHttpApiV2}/*'
443443

444-
ReturnDecodedParseBinRestApi:
444+
BinaryMediaTypeRestApi:
445445
Type: 'AWS::ApiGateway::RestApi'
446446
Properties:
447-
Name: !Sub '${AWS::StackName}-ReturnDecodedParseBinRestAPI'
447+
Name: !Sub '${AWS::StackName}-BinaryMediaTypeRestApi'
448448
EndpointConfiguration:
449449
Types:
450450
- REGIONAL
451451
BinaryMediaTypes:
452452
- '*/*'
453453

454-
ReturnDecodedParseBinRestApiResource:
454+
BinaryMediaTypeRestApiResource:
455455
Type: 'AWS::ApiGateway::Resource'
456456
Properties:
457-
ParentId: !GetAtt ReturnDecodedParseBinRestApi.RootResourceId
457+
ParentId: !GetAtt BinaryMediaTypeRestApi.RootResourceId
458458
PathPart: 'test'
459-
RestApiId: !Ref ReturnDecodedParseBinRestApi
459+
RestApiId: !Ref BinaryMediaTypeRestApi
460460

461-
ReturnDecodedParseBinRestApiMethod:
461+
BinaryMediaTypeRestApiMethod:
462462
Type: 'AWS::ApiGateway::Method'
463463
Properties:
464464
HttpMethod: POST
465-
ResourceId: !Ref ReturnDecodedParseBinRestApiResource
466-
RestApiId: !Ref ReturnDecodedParseBinRestApi
465+
ResourceId: !Ref BinaryMediaTypeRestApiResource
466+
RestApiId: !Ref BinaryMediaTypeRestApi
467467
AuthorizationType: NONE
468468
Integration:
469469
Type: AWS_PROXY
470470
IntegrationHttpMethod: POST
471471
Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ReturnDecodedParseBinLambdaFunction.Arn}/invocations'
472472

473-
ReturnDecodedParseBinRestApiDeployment:
473+
BinaryMediaTypeRestApiDeployment:
474474
Type: 'AWS::ApiGateway::Deployment'
475-
DependsOn: ReturnDecodedParseBinRestApiMethod
475+
DependsOn: BinaryMediaTypeRestApiMethod
476476
Properties:
477-
RestApiId: !Ref ReturnDecodedParseBinRestApi
477+
RestApiId: !Ref BinaryMediaTypeRestApi
478478
StageName: 'test'
479479

480-
LambdaPermissionReturnDecodedParseBinRestApi:
480+
LambdaPermissionBinaryMediaTypeRestApi:
481481
Type: 'AWS::Lambda::Permission'
482482
Properties:
483483
Action: 'lambda:InvokeFunction'
484484
FunctionName: !GetAtt ReturnDecodedParseBinLambdaFunction.Arn
485485
Principal: apigateway.amazonaws.com
486-
SourceArn: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ReturnDecodedParseBinRestApi}/*'
486+
SourceArn: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${BinaryMediaTypeRestApi}/*'
487+
488+
LambdaPermissionBinaryMediaTypeRestApi2:
489+
Type: 'AWS::Lambda::Permission'
490+
Properties:
491+
Action: 'lambda:InvokeFunction'
492+
FunctionName: !GetAtt ReturnFullEventLambdaFunction.Arn
493+
Principal: apigateway.amazonaws.com
494+
SourceArn: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${BinaryMediaTypeRestApi}/*'
487495

488496
Outputs:
489497
ParseAndReturnBodyRestApiId:
@@ -570,10 +578,10 @@ Outputs:
570578
Description: 'ARN of the Return Full Event Lambda Function'
571579
Value: !GetAtt ReturnFullEventLambdaFunction.Arn
572580

573-
ReturnDecodedParseBinRestApiId:
574-
Description: 'ID of the ReturnDecodedParseBin Media REST API'
575-
Value: !Ref ReturnDecodedParseBinRestApi
581+
BinaryMediaTypeRestApiId:
582+
Description: 'ID of the BinaryMediaTypeRest Media REST API'
583+
Value: !Ref BinaryMediaTypeRestApi
576584

577-
ReturnDecodedParseBinRestApiUrl:
578-
Description: 'URL of the ReturnDecodedParseBin Media REST API'
579-
Value: !Sub 'https://${ReturnDecodedParseBinRestApi}.execute-api.${AWS::Region}.amazonaws.com/test/test'
585+
BinaryMediaTypeRestApiUrl:
586+
Description: 'URL of the BinaryMediaTypeRest Media REST API'
587+
Value: !Sub 'https://${BinaryMediaTypeRestApi}.execute-api.${AWS::Region}.amazonaws.com/test/test'

0 commit comments

Comments
 (0)