Skip to content

Commit 3914bd0

Browse files
committed
feat: add capability for HttpV2
1 parent 7751d0c commit 3914bd0

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
using System.Text;
3+
using System.Text.Json;
4+
using Amazon.Lambda.APIGatewayEvents;
5+
using System.Threading.Tasks;
6+
7+
namespace Voxel.MiddyNet.HttpJsonBodyParserMiddleware
8+
{
9+
public class HttpV2JsonBodyParserMiddleware<T> : ILambdaMiddleware<APIGatewayHttpApiV2ProxyRequest, APIGatewayHttpApiV2ProxyResponse>
10+
{
11+
public Task Before(APIGatewayHttpApiV2ProxyRequest lambdaEvent, MiddyNetContext context)
12+
{
13+
if (!HasJsonContentHeaders(lambdaEvent))
14+
{
15+
context.AdditionalContext.Add("Body", lambdaEvent.Body);
16+
return Task.CompletedTask;
17+
}
18+
19+
if (lambdaEvent.IsBase64Encoded)
20+
{
21+
lambdaEvent.Body = Encoding.UTF8.GetString(Convert.FromBase64String(lambdaEvent.Body));
22+
}
23+
24+
var source = JsonSerializer.Deserialize<T>(lambdaEvent.Body);
25+
26+
27+
context.AdditionalContext.Add("Body", source);
28+
return Task.CompletedTask;
29+
}
30+
31+
private static bool HasJsonContentHeaders(APIGatewayHttpApiV2ProxyRequest lambdaEvent)
32+
{
33+
return lambdaEvent.Headers != null &&
34+
(lambdaEvent.Headers.ContainsKey("Content-Type") &&
35+
lambdaEvent.Headers["Content-Type"] == "application/json");
36+
}
37+
38+
public Task<APIGatewayHttpApiV2ProxyResponse> After(APIGatewayHttpApiV2ProxyResponse lambdaResponse, MiddyNetContext context) => Task.FromResult(lambdaResponse);
39+
}
40+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using System.Text.Json;
5+
using System.Threading.Tasks;
6+
using Amazon.Lambda.APIGatewayEvents;
7+
using Amazon.Lambda.Core;
8+
using FluentAssertions;
9+
using NSubstitute;
10+
using Xunit;
11+
12+
namespace Voxel.MiddyNet.HttpJsonBodyParserMiddleware.Tests
13+
{
14+
public class HttpV2JsonBodyParserMiddlewareShould
15+
{
16+
private MiddyNetContext context;
17+
private TestObject expectation;
18+
private string serializedExpectation;
19+
20+
public HttpV2JsonBodyParserMiddlewareShould()
21+
{
22+
context = new MiddyNetContext(Substitute.For<ILambdaContext>());
23+
expectation = new TestObject
24+
{
25+
foo = "bar"
26+
};
27+
serializedExpectation = JsonSerializer.Serialize(expectation);
28+
}
29+
30+
[Fact]
31+
public async Task ProcessTheJsonRequest()
32+
{
33+
var request = new APIGatewayHttpApiV2ProxyRequest()
34+
{
35+
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
36+
Body = serializedExpectation
37+
};
38+
var middleware = new HttpV2JsonBodyParserMiddleware<TestObject>();
39+
await middleware.Before(request, context);
40+
41+
context.AdditionalContext.ContainsKey("Body").Should().BeTrue();
42+
context.AdditionalContext["Body"].Should().BeEquivalentTo(expectation);
43+
}
44+
45+
[Fact]
46+
public void ErrorWhenJsonNotMapsToObject()
47+
{
48+
var source = "Make it broken" + serializedExpectation;
49+
var request = new APIGatewayHttpApiV2ProxyRequest()
50+
{
51+
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
52+
Body = source
53+
};
54+
var middleware = new HttpV2JsonBodyParserMiddleware<TestObject>();
55+
Action action = () => middleware.Before(request, context);
56+
57+
action.Should().Throw<Exception>().WithMessage("'M' is an invalid start of a value.*");
58+
}
59+
60+
[Fact]
61+
public async Task NotProcessTheBodyIfNoHeaderIsPassed()
62+
{
63+
var request = new APIGatewayHttpApiV2ProxyRequest()
64+
{
65+
Body = serializedExpectation
66+
};
67+
var middleware = new HttpV2JsonBodyParserMiddleware<TestObject>();
68+
await middleware.Before(request, context);
69+
70+
context.AdditionalContext.ContainsKey("Body").Should().BeTrue();
71+
context.AdditionalContext["Body"].Should().Be(serializedExpectation);
72+
}
73+
74+
[Fact]
75+
public async Task HandleABase64Body()
76+
{
77+
string base64Serialized = Convert.ToBase64String(Encoding.UTF8.GetBytes(serializedExpectation));
78+
79+
var request = new APIGatewayHttpApiV2ProxyRequest()
80+
{
81+
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
82+
IsBase64Encoded = true,
83+
Body = base64Serialized
84+
};
85+
86+
var middleware = new HttpV2JsonBodyParserMiddleware<TestObject>();
87+
await middleware.Before(request, context);
88+
89+
context.AdditionalContext.ContainsKey("Body").Should().BeTrue();
90+
context.AdditionalContext["Body"].Should().BeEquivalentTo(expectation);
91+
}
92+
93+
[Fact]
94+
public void HandleInvalidBase64Body()
95+
{
96+
var source = "Make it broken" + serializedExpectation;
97+
string base64Serialized = Convert.ToBase64String(Encoding.UTF8.GetBytes(source));
98+
99+
var request = new APIGatewayHttpApiV2ProxyRequest()
100+
{
101+
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
102+
IsBase64Encoded = true,
103+
Body = base64Serialized
104+
};
105+
106+
var middleware = new HttpV2JsonBodyParserMiddleware<TestObject>();
107+
Action action = () => middleware.Before(request, context);
108+
109+
action.Should().Throw<Exception>().WithMessage("'M' is an invalid start of a value.*");
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)