Skip to content

Commit 658f9af

Browse files
author
Bernt Røskar Brenna
committed
Scripts can set response status code
1 parent b4996f1 commit 658f9af

File tree

3 files changed

+43
-6
lines changed

3 files changed

+43
-6
lines changed

UnitTests/TestDynamicResponse.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,31 @@ public async Task ScriptsCanHandleEndpointObjects()
145145
{
146146
var endpoint = new Endpoint("foo", "bar");
147147

148-
var obj = (Dictionary <string, string>) endpoint.GetScriptObject("obj", () => new Dictionary<string, string>());
148+
endpoint.SetScriptObject("obj", new Dictionary<string, string>());
149+
var obj = (Dictionary <string, string>) endpoint.GetScriptObject("obj");
149150

150151
obj["a"] = "b";
151152
Assert.Equal(
152153
"b",
153-
await EvalAsync("using System.Collections.Generic; return ((Dictionary<string, string>)GetScriptObject(\"obj\", null))[\"a\"];", new RequestInfo { Endpoint = endpoint })
154+
await EvalAsync("using System.Collections.Generic; return ((Dictionary<string, string>)Endpoint.GetScriptObject(\"obj\"))[\"a\"];", new RequestInfo { Endpoint = endpoint })
154155
);
155156

156157
obj["a"] = "c";
157158
Assert.Equal(
158159
"c",
159-
await EvalAsync("using System.Collections.Generic; return ((Dictionary<string, string>)GetScriptObject(\"obj\", null))[\"a\"];", new RequestInfo { Endpoint = endpoint })
160+
await EvalAsync("using System.Collections.Generic; return ((Dictionary<string, string>)Endpoint.GetScriptObject(\"obj\"))[\"a\"];", new RequestInfo { Endpoint = endpoint })
160161
);
162+
}
163+
164+
[Fact]
165+
public async Task ScriptsCanSetResponseStatusCode()
166+
{
167+
var endpoint = new Endpoint("foo", "bar");
168+
var responseCreator = new LiteralDynamicResponseCreator("StatusCode = 102; return \"\";", endpoint);
169+
var response = new TestableHttpResponse();
170+
await responseCreator.CreateResponseAsync(new TestableHttpRequest("/", null), new byte[0], response, endpoint);
161171

172+
Assert.Equal(102, (int) response.HttpStatusCode);
162173
}
163174
}
164175

netmockery/DynamicResponseCreator.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Diagnostics;
88
using System.IO;
99
using System.Linq;
10+
using System.Net;
1011
using System.Reflection;
1112
#if !NET462
1213
using System.Runtime.Loader;
@@ -133,6 +134,17 @@ static public string ExecuteIncludes(string sourceCode, string directory)
133134
}
134135

135136
public abstract string SourceCode { get; }
137+
138+
protected override void AfterResponseWritten(RequestInfo requestInfo, IHttpResponseWrapper response)
139+
{
140+
Debug.Assert(requestInfo != null);
141+
Debug.Assert(response != null);
142+
143+
if (requestInfo.StatusCode != RequestInfo.USE_CONFIGURED_STATUS_CODE)
144+
{
145+
response.HttpStatusCode = (HttpStatusCode) requestInfo.StatusCode;
146+
}
147+
}
136148
}
137149

138150
public class LiteralDynamicResponseCreator : DynamicResponseCreatorBase

netmockery/ResponseCreator.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,16 @@ public interface IResponseCreatorWithFilename
8686

8787
public class RequestInfo
8888
{
89+
public const int USE_CONFIGURED_STATUS_CODE = -1;
90+
8991
private static object _locker = new object();
9092

9193
private DateTime _now = DateTime.MinValue;
9294

9395
public string RequestPath;
9496
public string QueryString;
9597
public string RequestBody;
98+
public int StatusCode = USE_CONFIGURED_STATUS_CODE;
9699
public IHeaderDictionary Headers;
97100
public Endpoint Endpoint;
98101
public string EndpointDirectory => Endpoint.Directory;
@@ -201,14 +204,15 @@ public void SetStatusCodeFromString(string value)
201204

202205
public override async Task<byte[]> CreateResponseAsync(IHttpRequestWrapper request, byte[] requestBody, IHttpResponseWrapper response, Endpoint endpoint)
203206
{
204-
var responseBody = await GetBodyAndExecuteReplacementsAsync(new RequestInfo
207+
var requestInfo = new RequestInfo
205208
{
206209
RequestPath = request.Path.ToString(),
207210
QueryString = request.QueryString.ToString(),
208-
RequestBody = Encoding.UTF8.GetString(requestBody),
211+
RequestBody = Encoding.UTF8.GetString(requestBody),
209212
Headers = request.Headers,
210213
Endpoint = endpoint
211-
});
214+
};
215+
var responseBody = await GetBodyAndExecuteReplacementsAsync(requestInfo);
212216
if (ContentType != null)
213217
{
214218
var contenttype = ContentType;
@@ -217,8 +221,18 @@ public override async Task<byte[]> CreateResponseAsync(IHttpRequestWrapper reque
217221
}
218222
response.HttpStatusCode = (HttpStatusCode) StatusCode;
219223
await response.WriteAsync(responseBody, Encoding);
224+
225+
AfterResponseWritten(requestInfo, response);
226+
220227
return Encoding.GetBytes(responseBody);
221228
}
229+
230+
protected virtual void AfterResponseWritten(RequestInfo requestInfo, IHttpResponseWrapper response)
231+
{
232+
// extension point, override to add logic in inheritors.
233+
// currently used by DynamicResponseCreator in order to let script code override status code
234+
}
235+
222236
public string ContentType {
223237
get { return ReplaceParameterReference(_contentType); }
224238
set { _contentType = value; }

0 commit comments

Comments
 (0)