diff --git a/UnitTests/TestDynamicResponse.cs b/UnitTests/TestDynamicResponse.cs index 6e04066..557d2ad 100644 --- a/UnitTests/TestDynamicResponse.cs +++ b/UnitTests/TestDynamicResponse.cs @@ -188,6 +188,29 @@ public async Task ScriptsCanSetResponseStatusCode() Assert.Equal(102, (int) response.HttpStatusCode); } + + [Fact] + public async Task ScriptsCanSetContentType() + { + var endpoint = new Endpoint("foo", "bar"); + var responseCreator = new LiteralDynamicResponseCreator("ContentType = \"image/png\"; return \"\";", endpoint); + var response = new TestableHttpResponse(); + await responseCreator.CreateResponseAsync(new TestableHttpRequest("/", null), new byte[0], response, endpoint); + + Assert.Equal("image/png", response.ContentType); + } + + [Fact] + public async Task ScriptWithoutReturnValueThrowsException() + { + var endpoint = new Endpoint("foo", "bar"); + var responseCreator = new LiteralDynamicResponseCreator("ContentType = \"image/png\";", endpoint); + var response = new TestableHttpResponse(); + await Assert.ThrowsAsync( + typeof(ArgumentNullException), + async () => await responseCreator.CreateResponseAsync(new TestableHttpRequest("/", null), new byte[0], response, endpoint) + ); + } } public class TestCheckScriptModifications : IDisposable diff --git a/netmockery/DynamicResponseCreator.cs b/netmockery/DynamicResponseCreator.cs index 894446d..bb08f88 100644 --- a/netmockery/DynamicResponseCreator.cs +++ b/netmockery/DynamicResponseCreator.cs @@ -151,6 +151,20 @@ protected override void SetStatusCode(RequestInfo requestInfo, IHttpResponseWrap base.SetStatusCode(requestInfo, response); } } + + protected override void SetContentType(RequestInfo requestInfo, IHttpResponseWrapper response) + { + Debug.Assert(requestInfo != null); + Debug.Assert(response != null); + if (requestInfo.ContentType != RequestInfo.USE_CONFIGURED_CONTENT_TYPE) + { + response.ContentType = requestInfo.ContentType; + } + else + { + base.SetContentType(requestInfo, response); + } + } } public class LiteralDynamicResponseCreator : DynamicResponseCreatorBase diff --git a/netmockery/ResponseCreator.cs b/netmockery/ResponseCreator.cs index 97be0e6..28a44cc 100644 --- a/netmockery/ResponseCreator.cs +++ b/netmockery/ResponseCreator.cs @@ -87,6 +87,7 @@ public interface IResponseCreatorWithFilename public class RequestInfo { public const int USE_CONFIGURED_STATUS_CODE = -1; + public const string USE_CONFIGURED_CONTENT_TYPE = null; private static object _locker = new object(); @@ -96,6 +97,7 @@ public class RequestInfo public string QueryString; public string RequestBody; public int StatusCode = USE_CONFIGURED_STATUS_CODE; + public string ContentType = USE_CONFIGURED_CONTENT_TYPE; public IHeaderDictionary Headers; public Endpoint Endpoint; public string EndpointDirectory => Endpoint.Directory; @@ -213,16 +215,25 @@ public override async Task CreateResponseAsync(IHttpRequestWrapper reque Endpoint = endpoint }; var responseBody = await GetBodyAndExecuteReplacementsAsync(requestInfo); + + SetContentType(requestInfo, response); + SetStatusCode(requestInfo, response); + + await response.WriteAsync(responseBody, Encoding); + return Encoding.GetBytes(responseBody); + } + + protected virtual void SetContentType(RequestInfo requestInfo, IHttpResponseWrapper response) + { + // extension point, override to add logic in inheritors. + // currently used by DynamicResponseCreator in order to let script code override content type + if (ContentType != null) { var contenttype = ContentType; contenttype += $"; charset={Encoding.WebName}"; response.ContentType = contenttype; } - - SetStatusCode(requestInfo, response); - await response.WriteAsync(responseBody, Encoding); - return Encoding.GetBytes(responseBody); } protected virtual void SetStatusCode(RequestInfo requestInfo, IHttpResponseWrapper response)