-
Notifications
You must be signed in to change notification settings - Fork 475
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
3 changed files
with
280 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
...s/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Extensions/ApiGatewayResponseExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
namespace Amazon.Lambda.TestTool.Extensions; | ||
|
||
using Amazon.Lambda.APIGatewayEvents; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.Extensions.Primitives; | ||
using System; | ||
using System.IO; | ||
using System.Text; | ||
|
||
/// <summary> | ||
/// Provides extension methods for converting API Gateway responses to HttpResponse objects. | ||
/// </summary> | ||
public static class ApiGatewayResponseExtensions | ||
{ | ||
/// <summary> | ||
/// Converts an APIGatewayProxyResponse to an HttpResponse. | ||
/// </summary> | ||
/// <param name="apiResponse">The API Gateway proxy response to convert.</param> | ||
/// <returns>An HttpResponse object representing the API Gateway response.</returns> | ||
public static HttpResponse ToHttpResponse(this APIGatewayProxyResponse apiResponse) | ||
{ | ||
var httpContext = new DefaultHttpContext(); | ||
var response = httpContext.Response; | ||
|
||
response.StatusCode = apiResponse.StatusCode; | ||
|
||
SetResponseHeaders(response, apiResponse.Headers, apiResponse.MultiValueHeaders); | ||
|
||
SetResponseBody(response, apiResponse.Body, apiResponse.IsBase64Encoded); | ||
|
||
return response; | ||
} | ||
|
||
/// <summary> | ||
/// Converts an APIGatewayHttpApiV2ProxyResponse to an HttpResponse. | ||
/// </summary> | ||
/// <param name="apiResponse">The API Gateway HTTP API v2 proxy response to convert.</param> | ||
/// <returns>An HttpResponse object representing the API Gateway response.</returns> | ||
public static HttpResponse ToHttpResponse(this APIGatewayHttpApiV2ProxyResponse apiResponse) | ||
{ | ||
var httpContext = new DefaultHttpContext(); | ||
var response = httpContext.Response; | ||
|
||
response.StatusCode = apiResponse.StatusCode; | ||
|
||
SetResponseHeaders(response, apiResponse.Headers); | ||
|
||
if (apiResponse.Cookies != null) | ||
{ | ||
foreach (var cookie in apiResponse.Cookies) | ||
{ | ||
response.Headers.Append("Set-Cookie", cookie); | ||
} | ||
} | ||
|
||
SetResponseBody(response, apiResponse.Body, apiResponse.IsBase64Encoded); | ||
|
||
return response; | ||
} | ||
|
||
/// <summary> | ||
/// Sets the headers on the HttpResponse object. | ||
/// </summary> | ||
/// <param name="response">The HttpResponse object to modify.</param> | ||
/// <param name="headers">The single-value headers to set.</param> | ||
/// <param name="multiValueHeaders">The multi-value headers to set.</param> | ||
private static void SetResponseHeaders(HttpResponse response, IDictionary<string, string>? headers, IDictionary<string, IList<string>>? multiValueHeaders = null) | ||
{ | ||
if (headers != null) | ||
{ | ||
foreach (var header in headers) | ||
{ | ||
response.Headers[header.Key] = header.Value; | ||
} | ||
} | ||
|
||
if (multiValueHeaders != null) | ||
{ | ||
foreach (var header in multiValueHeaders) | ||
{ | ||
response.Headers[header.Key] = new StringValues(header.Value.ToArray()); | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Sets the body of the HttpResponse object. | ||
/// </summary> | ||
/// <param name="response">The HttpResponse object to modify.</param> | ||
/// <param name="body">The body content to set.</param> | ||
/// <param name="isBase64Encoded">Indicates whether the body is Base64 encoded.</param> | ||
private static void SetResponseBody(HttpResponse response, string? body, bool isBase64Encoded) | ||
{ | ||
if (!string.IsNullOrEmpty(body)) | ||
{ | ||
byte[] bodyBytes; | ||
if (isBase64Encoded) | ||
{ | ||
bodyBytes = Convert.FromBase64String(body); | ||
} | ||
else | ||
{ | ||
bodyBytes = Encoding.UTF8.GetBytes(body); | ||
} | ||
response.Body = new MemoryStream(bodyBytes); | ||
} | ||
} | ||
} |
170 changes: 170 additions & 0 deletions
170
...v2/tests/Amazon.Lambda.TestTool.UnitTests/Extensions/ApiGatewayResponseExtensionsTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
namespace Amazon.Lambda.TestTool.UnitTests.Extensions; | ||
|
||
using Amazon.Lambda.APIGatewayEvents; | ||
using Amazon.Lambda.TestTool.Extensions; | ||
using System.IO; | ||
using System.Text; | ||
using Xunit; | ||
|
||
public class ApiGatewayResponseExtensionsTests | ||
{ | ||
[Fact] | ||
public void ToHttpResponse_APIGatewayProxyResponse_SetsCorrectStatusCode() | ||
{ | ||
var apiResponse = new APIGatewayProxyResponse | ||
{ | ||
StatusCode = 200 | ||
}; | ||
|
||
var httpResponse = apiResponse.ToHttpResponse(); | ||
|
||
Assert.Equal(200, httpResponse.StatusCode); | ||
} | ||
|
||
[Fact] | ||
public void ToHttpResponse_APIGatewayProxyResponse_SetsHeaders() | ||
{ | ||
var apiResponse = new APIGatewayProxyResponse | ||
{ | ||
Headers = new Dictionary<string, string> | ||
{ | ||
{ "Content-Type", "application/json" }, | ||
{ "X-Custom-Header", "CustomValue" } | ||
} | ||
}; | ||
|
||
var httpResponse = apiResponse.ToHttpResponse(); | ||
|
||
Assert.Equal("application/json", httpResponse.Headers["Content-Type"]); | ||
Assert.Equal("CustomValue", httpResponse.Headers["X-Custom-Header"]); | ||
} | ||
|
||
[Fact] | ||
public void ToHttpResponse_APIGatewayProxyResponse_SetsMultiValueHeaders() | ||
{ | ||
var apiResponse = new APIGatewayProxyResponse | ||
{ | ||
MultiValueHeaders = new Dictionary<string, IList<string>> | ||
{ | ||
{ "X-Multi-Header", new List<string> { "Value1", "Value2" } } | ||
} | ||
}; | ||
|
||
var httpResponse = apiResponse.ToHttpResponse(); | ||
|
||
Assert.Equal(new[] { "Value1", "Value2" }, httpResponse.Headers["X-Multi-Header"]); | ||
} | ||
|
||
[Fact] | ||
public void ToHttpResponse_APIGatewayProxyResponse_SetsBodyNonBase64() | ||
{ | ||
var apiResponse = new APIGatewayProxyResponse | ||
{ | ||
Body = "Hello, World!", | ||
IsBase64Encoded = false | ||
}; | ||
|
||
var httpResponse = apiResponse.ToHttpResponse(); | ||
|
||
httpResponse.Body.Seek(0, SeekOrigin.Begin); | ||
var bodyContent = new StreamReader(httpResponse.Body).ReadToEnd(); | ||
Assert.Equal("Hello, World!", bodyContent); | ||
} | ||
|
||
[Fact] | ||
public void ToHttpResponse_APIGatewayProxyResponse_SetsBodyBase64() | ||
{ | ||
var originalBody = "Hello, World!"; | ||
var base64Body = Convert.ToBase64String(Encoding.UTF8.GetBytes(originalBody)); | ||
var apiResponse = new APIGatewayProxyResponse | ||
{ | ||
Body = base64Body, | ||
IsBase64Encoded = true | ||
}; | ||
|
||
var httpResponse = apiResponse.ToHttpResponse(); | ||
|
||
httpResponse.Body.Seek(0, SeekOrigin.Begin); | ||
var bodyContent = new StreamReader(httpResponse.Body).ReadToEnd(); | ||
Assert.Equal(originalBody, bodyContent); | ||
} | ||
|
||
[Fact] | ||
public void ToHttpResponse_APIGatewayHttpApiV2ProxyResponse_SetsCorrectStatusCode() | ||
{ | ||
var apiResponse = new APIGatewayHttpApiV2ProxyResponse | ||
{ | ||
StatusCode = 201 | ||
}; | ||
|
||
var httpResponse = apiResponse.ToHttpResponse(); | ||
|
||
Assert.Equal(201, httpResponse.StatusCode); | ||
} | ||
|
||
[Fact] | ||
public void ToHttpResponse_APIGatewayHttpApiV2ProxyResponse_SetsHeaders() | ||
{ | ||
var apiResponse = new APIGatewayHttpApiV2ProxyResponse | ||
{ | ||
Headers = new Dictionary<string, string> | ||
{ | ||
{ "Content-Type", "application/xml" }, | ||
{ "X-Custom-Header", "CustomValue" } | ||
} | ||
}; | ||
|
||
var httpResponse = apiResponse.ToHttpResponse(); | ||
|
||
Assert.Equal("application/xml", httpResponse.Headers["Content-Type"]); | ||
Assert.Equal("CustomValue", httpResponse.Headers["X-Custom-Header"]); | ||
} | ||
|
||
[Fact] | ||
public void ToHttpResponse_APIGatewayHttpApiV2ProxyResponse_SetsCookies() | ||
{ | ||
var apiResponse = new APIGatewayHttpApiV2ProxyResponse | ||
{ | ||
Cookies = new[] { "session=abc123; Path=/", "theme=dark; Max-Age=3600" } | ||
}; | ||
|
||
var httpResponse = apiResponse.ToHttpResponse(); | ||
|
||
Assert.Contains(httpResponse.Headers["Set-Cookie"], v => v == "session=abc123; Path=/"); | ||
Assert.Contains(httpResponse.Headers["Set-Cookie"], v => v == "theme=dark; Max-Age=3600"); | ||
} | ||
|
||
[Fact] | ||
public void ToHttpResponse_APIGatewayHttpApiV2ProxyResponse_SetsBodyNonBase64() | ||
{ | ||
var apiResponse = new APIGatewayHttpApiV2ProxyResponse | ||
{ | ||
Body = "Hello, API Gateway v2!", | ||
IsBase64Encoded = false | ||
}; | ||
|
||
var httpResponse = apiResponse.ToHttpResponse(); | ||
|
||
httpResponse.Body.Seek(0, SeekOrigin.Begin); | ||
var bodyContent = new StreamReader(httpResponse.Body).ReadToEnd(); | ||
Assert.Equal("Hello, API Gateway v2!", bodyContent); | ||
} | ||
|
||
[Fact] | ||
public void ToHttpResponse_APIGatewayHttpApiV2ProxyResponse_SetsBodyBase64() | ||
{ | ||
var originalBody = "Hello, API Gateway v2!"; | ||
var base64Body = Convert.ToBase64String(Encoding.UTF8.GetBytes(originalBody)); | ||
var apiResponse = new APIGatewayHttpApiV2ProxyResponse | ||
{ | ||
Body = base64Body, | ||
IsBase64Encoded = true | ||
}; | ||
|
||
var httpResponse = apiResponse.ToHttpResponse(); | ||
|
||
httpResponse.Body.Seek(0, SeekOrigin.Begin); | ||
var bodyContent = new StreamReader(httpResponse.Body).ReadToEnd(); | ||
Assert.Equal(originalBody, bodyContent); | ||
} | ||
} |