diff --git a/.github/releases/v0.9.0-beta4.md b/.github/releases/v0.9.0-beta4.md
index c0b5ffeb..48975eaf 100644
--- a/.github/releases/v0.9.0-beta4.md
+++ b/.github/releases/v0.9.0-beta4.md
@@ -1,6 +1,8 @@
# Enhancements
- CloudFormationStackEvent objects are now serializable.
+- ResponseURL is now an optional argument to custom resource requests, to allow for easier testing.
+- The lambda output for Custom Resources is now the full response that would've been sent to CloudFormation, rather than just the output data.
# Bug Fixes
diff --git a/src/CustomResource/CustomResourceLambdaHost.cs b/src/CustomResource/CustomResourceLambdaHost.cs
index 66628fa4..d1c38790 100644
--- a/src/CustomResource/CustomResourceLambdaHost.cs
+++ b/src/CustomResource/CustomResourceLambdaHost.cs
@@ -15,7 +15,7 @@ namespace Lambdajection.CustomResource
{
///
public sealed class CustomResourceLambdaHost
- : LambdaHostBase, TLambdaOutput, TLambdaStartup, TLambdaConfigurator, TLambdaConfigFactory>
+ : LambdaHostBase, CustomResourceResponse, TLambdaStartup, TLambdaConfigurator, TLambdaConfigFactory>
where TLambda : class, ICustomResourceProvider
where TLambdaParameter : class
where TLambdaOutput : class, ICustomResourceOutputData
@@ -35,13 +35,13 @@ public CustomResourceLambdaHost()
/// Initializes a new instance of the class.
///
/// The builder action to run on the lambda.
- internal CustomResourceLambdaHost(Action, TLambdaOutput, TLambdaStartup, TLambdaConfigurator, TLambdaConfigFactory>> build)
+ internal CustomResourceLambdaHost(Action, CustomResourceResponse, TLambdaStartup, TLambdaConfigurator, TLambdaConfigFactory>> build)
: base(build)
{
}
///
- public override async Task InvokeLambda(
+ public override async Task> InvokeLambda(
Stream inputStream,
CancellationToken cancellationToken = default
)
@@ -92,14 +92,17 @@ public override async Task InvokeLambda(
};
}
- await httpClient.PutJson(
- requestUri: input.ResponseURL,
- payload: response,
- contentType: null,
- cancellationToken: cancellationToken
- );
+ if (input.ResponseURL != null)
+ {
+ await httpClient.PutJson(
+ requestUri: input.ResponseURL,
+ payload: response,
+ contentType: null,
+ cancellationToken: cancellationToken
+ );
+ }
- return response.Data!;
+ return response;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
diff --git a/src/CustomResource/CustomResourceRequest.cs b/src/CustomResource/CustomResourceRequest.cs
index 1d818b5b..ac8b685d 100644
--- a/src/CustomResource/CustomResourceRequest.cs
+++ b/src/CustomResource/CustomResourceRequest.cs
@@ -24,7 +24,7 @@ public class CustomResourceRequest
/// has been created/updated/deleted.
///
/// The response URL.
- public virtual Uri ResponseURL { get; set; } = new Uri("http://localhost");
+ public virtual Uri? ResponseURL { get; set; }
///
/// Gets or sets the Id of the CloudFormation stack that the
diff --git a/tests/Unit/CustomResource/CustomResourceLambdaHostTests.cs b/tests/Unit/CustomResource/CustomResourceLambdaHostTests.cs
index 5a1d9709..da53c791 100644
--- a/tests/Unit/CustomResource/CustomResourceLambdaHostTests.cs
+++ b/tests/Unit/CustomResource/CustomResourceLambdaHostTests.cs
@@ -196,7 +196,7 @@ [Substitute] IHttpClient httpClient
await host.InvokeLambda(inputStream, cancellationToken);
await httpClient.Received().PutJson(
- Is(request.ResponseURL),
+ Is(request.ResponseURL!),
Is>(response =>
response.Status == CustomResourceResponseStatus.Success &&
response.Data == data
@@ -234,7 +234,7 @@ [Substitute] IHttpClient httpClient
await host.InvokeLambda(inputStream, cancellationToken);
await httpClient.Received().PutJson(
- Is(request.ResponseURL),
+ Is(request.ResponseURL!),
Is>(response =>
response.Status == CustomResourceResponseStatus.Success &&
response.StackId == stackId
@@ -272,7 +272,7 @@ [Substitute] IHttpClient httpClient
await host.InvokeLambda(inputStream, cancellationToken);
await httpClient.Received().PutJson(
- Is(request.ResponseURL),
+ Is(request.ResponseURL!),
Is>(response =>
response.Status == CustomResourceResponseStatus.Success &&
response.RequestId == requestId
@@ -310,7 +310,7 @@ [Substitute] IHttpClient httpClient
await host.InvokeLambda(inputStream, cancellationToken);
await httpClient.Received().PutJson(
- Is(request.ResponseURL),
+ Is(request.ResponseURL!),
Is>(response =>
response.Status == CustomResourceResponseStatus.Success &&
response.LogicalResourceId == logicalResourceId
@@ -350,7 +350,7 @@ [Substitute] IHttpClient httpClient
await host.InvokeLambda(inputStream, cancellationToken);
await httpClient.Received().PutJson(
- Is(request.ResponseURL),
+ Is(request.ResponseURL!),
Is>(response =>
response.Status == CustomResourceResponseStatus.Success &&
response.PhysicalResourceId == physicalResourceId
@@ -360,6 +360,42 @@ await httpClient.Received().PutJson(
);
}
+ [Test, Auto]
+ public async Task ShouldNotRespondSuccessIfResponseURLIsNull(
+ ServiceCollection serviceCollection,
+ string stackId,
+ JsonSerializer serializer,
+ CustomResourceRequest