Skip to content

Commit 45c8516

Browse files
author
bbeversdorf
authored
SL-8459 - Creates Agent Profile Delegate (#25)
1 parent 8faf307 commit 45c8516

5 files changed

Lines changed: 129 additions & 71 deletions

File tree

Float.TinCan.LocalLRSServer.Tests/AgentProfile.Tests.cs

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Net;
23
using System.Text;
34
using System.Threading.Tasks;
45
using TinCan;
@@ -12,6 +13,7 @@ public sealed class TestAgentProfile: IDisposable
1213
class StubServerDelegate : ILRSServerDelegate
1314
{
1415
readonly Agent agent;
16+
AgentProfileDocument tempProfileDocument;
1517

1618
internal StubServerDelegate(Agent agent)
1719
{
@@ -20,6 +22,11 @@ internal StubServerDelegate(Agent agent)
2022

2123
public AgentProfileDocument AgentProfileDocumentForProfileId(string profileId)
2224
{
25+
if (tempProfileDocument != null)
26+
{
27+
return tempProfileDocument;
28+
}
29+
2330
return new AgentProfileDocument
2431
{
2532
agent = agent,
@@ -32,6 +39,23 @@ public string GetAccessConrolAllowOrigin()
3239
{
3340
return null;
3441
}
42+
43+
public void AlterAgentProfileResponse(HttpListenerRequest request, ref HttpListenerResponse response, ref AgentProfileDocument profileDocument)
44+
{
45+
if (request.HttpMethod.ToString() != "GET")
46+
{
47+
tempProfileDocument = new AgentProfileDocument
48+
{
49+
agent = profileDocument.agent,
50+
content = profileDocument.id != "testing_save" ? profileDocument.content : Encoding.UTF8.GetBytes("this is transformed test content"),
51+
contentType = profileDocument.contentType,
52+
id = profileDocument.id,
53+
timestamp = profileDocument.timestamp,
54+
etag = profileDocument.etag
55+
};
56+
}
57+
return;
58+
}
3559
}
3660

3761
readonly LRSServer localLRS;
@@ -64,38 +88,38 @@ public TestAgentProfile()
6488
[Fact]
6589
public async Task TestCanSaveAgentProfile()
6690
{
67-
var didReceive = false;
68-
var document = new AgentProfileDocument();
69-
70-
localLRS.AgentProfileDocumentReceived += (lrs, args) =>
71-
{
72-
didReceive = true;
73-
document = args.AgentProfileDocument;
74-
};
75-
7691
var doc = new AgentProfileDocument
7792
{
78-
id = "test_id",
93+
id = "testing_save",
7994
timestamp = new DateTime(),
8095
contentType = "text/html",
8196
content = Encoding.UTF8.GetBytes("this is test content"),
8297
agent = testAgent
8398
};
8499

85-
var response = await remoteLRS.SaveAgentProfile(doc);
100+
var saveResponse = await remoteLRS.SaveAgentProfile(doc);
101+
Assert.True(saveResponse.success);
102+
103+
var response = await remoteLRS.RetrieveAgentProfile("test_id", testAgent);
86104

105+
var result = Encoding.UTF8.GetString(response.content.content);
87106
Assert.NotNull(response);
88107
Assert.True(response.success);
89-
Assert.True(didReceive);
90-
Assert.Equal("test_id", document.id);
91108

92109
// BUG: remoteLRS.SaveAgentProfile
93110
// does not decode mbox so
94111
// we cannot test for agent equality
95-
Assert.NotNull(document.agent);
96-
Assert.True(document.agent.account.name == "Example.com");
97-
Assert.NotNull(document.content);
98-
Assert.True(document.contentType == "text/html");
112+
Assert.NotNull(response);
113+
Assert.NotNull(response.content);
114+
Assert.Null(response.errMsg);
115+
Assert.Null(response.Error);
116+
Assert.Null(response.httpException);
117+
Assert.True(response.success);
118+
Assert.Equal("application/json", response.content.contentType);
119+
Assert.Null(response.content.etag);
120+
Assert.Null(response.content.id);
121+
Assert.NotEmpty(response.content.content);
122+
Assert.Equal("this is transformed test content", result);
99123
}
100124

101125
[Fact]
@@ -131,7 +155,7 @@ public async Task TestCanGetAgentProfile()
131155
// Assert.Equal(testAgent, response.content.agent);
132156
// Assert.Equal("test_id", response.content.id);
133157

134-
Assert.Equal("this is a test string", result);
158+
Assert.Equal("this is test content", result);
135159
}
136160

137161
~TestAgentProfile()

Float.TinCan.LocalLRSServer.Tests/LRSServer.Tests.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Threading.Tasks;
1+
using System.Net;
2+
using System.Threading.Tasks;
23
using TinCan;
34
using TinCan.Documents;
45
using Xunit;
@@ -16,6 +17,11 @@ public string GetAccessConrolAllowOrigin()
1617
{
1718
return null;
1819
}
20+
21+
public void AlterAgentProfileResponse(HttpListenerRequest request, ref HttpListenerResponse response, ref AgentProfileDocument profileDocument)
22+
{
23+
return;
24+
}
1925
}
2026

2127
public class LRSServerTests

Float.TinCan.LocalLRSServer/HttpServer.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,11 @@ protected static void WriteToStream(HttpListenerResponse response, byte[] conten
188188
throw new ArgumentNullException(nameof(response));
189189
}
190190

191-
if (contentBytes == null)
191+
if (contentBytes == null && statusCode != HttpStatusCode.NoContent)
192192
{
193193
throw new ArgumentNullException(nameof(contentBytes));
194194
}
195195

196-
var contentLength = contentBytes.Length;
197-
response.ContentLength64 = contentLength;
198-
199196
if (contentType != null)
200197
{
201198
response.ContentType = contentType.ToString();
@@ -206,7 +203,13 @@ protected static void WriteToStream(HttpListenerResponse response, byte[] conten
206203
response.StatusCode = (int)statusCode;
207204
}
208205

209-
response.OutputStream.Write(contentBytes, 0, contentLength);
206+
if (contentBytes != null)
207+
{
208+
var contentLength = contentBytes.Length;
209+
response.ContentLength64 = contentLength;
210+
response.OutputStream.Write(contentBytes, 0, contentLength);
211+
}
212+
210213
response.OutputStream.Close();
211214
}
212215

Float.TinCan.LocalLRSServer/ILRSServerDelegate.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using TinCan.Documents;
1+
using System.Net;
2+
using TinCan.Documents;
23

34
namespace Float.TinCan.LocalLRSServer
45
{
@@ -20,5 +21,13 @@ public interface ILRSServerDelegate
2021
/// </summary>
2122
/// <returns>The header value for Access-Control-Allow-Origin.</returns>
2223
string GetAccessConrolAllowOrigin();
24+
25+
/// <summary>
26+
/// Delegate method to alter a response for AgentProfile.
27+
/// </summary>
28+
/// <param name="request">The HTTP request to get query params from.</param>
29+
/// <param name="response">The current HTTP response.</param>
30+
/// <param name="profileDocument">The profile document.</param>
31+
public void AlterAgentProfileResponse(HttpListenerRequest request, ref HttpListenerResponse response, ref AgentProfileDocument profileDocument);
2332
}
2433
}

Float.TinCan.LocalLRSServer/LRSServer.cs

Lines changed: 62 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -247,66 +247,82 @@ void HandleStateRequest(HttpListenerRequest request, HttpListenerResponse respon
247247
/// <param name="response">The HTTP response, which will get a No Content response.</param>
248248
void HandleAgentProfileRequest(HttpListenerRequest request, HttpListenerResponse response)
249249
{
250-
var method = new HttpMethod(request.HttpMethod);
250+
var method = new HttpMethod(request.HttpMethod).ToString();
251251
var profileIdString = request.QueryString["profileId"];
252252
AgentProfileDocument profileDocument = null;
253-
254-
if (method == HttpMethod.Get)
253+
try
255254
{
256-
if (string.IsNullOrWhiteSpace(profileIdString))
255+
switch (method)
257256
{
258-
// todo: return all available IDs
257+
case string m when HttpMethod.Get.ToString() == method:
258+
if (string.IsNullOrWhiteSpace(profileIdString))
259+
{
260+
// todo: return all available IDs
259261
#pragma warning disable CA1303 // Do not pass literals as localized parameters
260-
throw new NotImplementedException("GET requests for all documents are not yet implemented");
262+
throw new NotImplementedException("GET requests for all documents are not yet implemented");
261263
#pragma warning restore CA1303 // Do not pass literals as localized parameters
262-
}
264+
}
265+
266+
if (serverDelegate != null)
267+
{
268+
profileDocument = serverDelegate.AgentProfileDocumentForProfileId(profileIdString);
269+
}
270+
271+
WriteToStream(response, profileDocument.content, ContentType.Json, HttpStatusCode.OK);
272+
return;
273+
case string m when HttpMethod.Post.ToString() == method:
274+
case string m1 when HttpMethod.Put.ToString() == method:
275+
profileDocument = new AgentProfileDocument
276+
{
277+
id = WebUtility.UrlDecode(profileIdString),
278+
};
279+
280+
var agentString = WebUtility.UrlDecode(request.QueryString["agent"]);
281+
282+
if (agentString != null)
283+
{
284+
profileDocument.agent = new Agent(new StringOfJSON(agentString));
285+
}
286+
287+
Encoding encoding = request.ContentEncoding;
288+
var bytes = new byte[request.ContentLength64];
289+
request.InputStream.Read(bytes, 0, (int)request.ContentLength64);
290+
profileDocument.content = bytes;
291+
profileDocument.contentType = request.ContentType;
292+
RaiseAgentProfileDocumentEvent(new AgentProfileDocumentEventArgs(profileDocument));
293+
294+
if (serverDelegate != null)
295+
{
296+
serverDelegate.AlterAgentProfileResponse(request, ref response, ref profileDocument);
297+
}
263298

264-
if (serverDelegate != null)
265-
{
266-
profileDocument = serverDelegate.AgentProfileDocumentForProfileId(profileIdString);
267-
}
268-
}
269-
else if (method == HttpMethod.Delete)
270-
{
271-
// todo: implement delete requests
299+
SendResponse(response, HttpStatusCode.NoContent);
300+
return;
301+
case string m when HttpMethod.Delete.ToString() == method:
302+
if (serverDelegate != null)
303+
{
304+
serverDelegate.AlterAgentProfileResponse(request, ref response, ref profileDocument);
305+
SendResponse(response, HttpStatusCode.NoContent);
306+
}
307+
else
308+
{
309+
// todo: implement delete requests
272310
#pragma warning disable CA1303 // Do not pass literals as localized parameters
273-
throw new NotImplementedException("DELETE requests are not yet implemented");
311+
throw new NotImplementedException("DELETE requests are not yet implemented");
274312
#pragma warning restore CA1303 // Do not pass literals as localized parameters
275-
}
276-
else if (method == HttpMethod.Put || method == HttpMethod.Post)
277-
{
278-
profileDocument = new AgentProfileDocument
279-
{
280-
id = WebUtility.UrlDecode(profileIdString),
281-
};
282-
283-
var agentString = WebUtility.UrlDecode(request.QueryString["agent"]);
313+
}
284314

285-
if (agentString != null)
286-
{
287-
profileDocument.agent = new Agent(new StringOfJSON(agentString));
315+
return;
316+
default:
317+
throw new InvalidOperationException($"Only GET, DELETE, PUT, and POST are supported for {nameof(HandleAgentProfileRequest)}. Received {method}");
288318
}
289-
290-
Encoding encoding = request.ContentEncoding;
291-
var bytes = new byte[request.ContentLength64];
292-
request.InputStream.Read(bytes, 0, (int)request.ContentLength64);
293-
profileDocument.content = bytes;
294-
profileDocument.contentType = request.ContentType;
295-
296-
RaiseAgentProfileDocumentEvent(new AgentProfileDocumentEventArgs(profileDocument));
297-
}
298-
else
299-
{
300-
throw new InvalidOperationException($"Only GET, DELETE, PUT, and POST are supported for {nameof(HandleAgentProfileRequest)}. Received {method}");
301319
}
302320

303-
if (method == HttpMethod.Put || method == HttpMethod.Post || method == HttpMethod.Delete)
304-
{
305-
SendResponse(response, HttpStatusCode.NoContent);
306-
}
307-
else
321+
#pragma warning disable CA1031 // Do not catch general exception types
322+
catch
323+
#pragma warning restore CA1031 // Do not catch general exception types
308324
{
309-
WriteToStream(response, profileDocument.content, ContentType.Json, HttpStatusCode.OK);
325+
SendResponse(response, HttpStatusCode.BadRequest);
310326
}
311327
}
312328

0 commit comments

Comments
 (0)