Skip to content

Commit 960ca21

Browse files
author
Chris Santero
committed
Merge branch 'master' into 0-4-0
2 parents 6b014f1 + 9804f41 commit 960ca21

9 files changed

Lines changed: 127 additions & 36 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"tags": [
3+
{
4+
"id": "1",
5+
"text": "Ember"
6+
}, {
7+
"id": "2",
8+
"text": "React"
9+
}, {
10+
"id": "3",
11+
"text": "Angular"
12+
}
13+
]
14+
}
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
{
22
"errors": [
33
{
4-
"id": "TEST-ERROR-ID",
4+
"id": "OUTER-ID",
55
"status": "500",
66
"title": "System.Exception",
7-
"detail": "This is the exception message!",
8-
"inner": null,
9-
"stackTrace": "Stack trace would go here"
7+
"detail": "Outer exception message",
8+
"stackTrace": "Outer stack trace",
9+
"inner": {
10+
"id": "INNER-ID",
11+
"status": "500",
12+
"title": "Castle.Proxies.ExceptionProxy",
13+
"detail": "Inner exception message",
14+
"stackTrace": "Inner stack trace",
15+
"inner": null
16+
}
1017
}
1118
]
1219
}

JSONAPI.Tests/JSONAPI.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
<Compile Include="Json\LinkTemplateTests.cs" />
9191
<Compile Include="Models\Author.cs" />
9292
<Compile Include="Models\Comment.cs" />
93+
<Compile Include="Models\Tag.cs" />
9394
<Compile Include="Models\Sample.cs" />
9495
<Compile Include="Models\Post.cs" />
9596
<Compile Include="Models\UserGroup.cs" />
@@ -103,6 +104,9 @@
103104
</ItemGroup>
104105
<ItemGroup>
105106
<None Include="app.config" />
107+
<None Include="Data\ByteIdSerializationTest.json">
108+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
109+
</None>
106110
<None Include="Data\ReformatsRawJsonStringWithUnquotedKeys.json">
107111
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
108112
</None>

JSONAPI.Tests/Json/ErrorSerializerTests.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,14 @@
44
using FluentAssertions;
55
using JSONAPI.Json;
66
using Microsoft.VisualStudio.TestTools.UnitTesting;
7+
using Moq;
78
using Newtonsoft.Json;
89

910
namespace JSONAPI.Tests.Json
1011
{
1112
[TestClass]
1213
public class ErrorSerializerTests
1314
{
14-
private class TestErrorIdProvider : IErrorIdProvider
15-
{
16-
public string GenerateId(HttpError error)
17-
{
18-
return "TEST-ERROR-ID";
19-
}
20-
}
21-
2215
[TestMethod]
2316
public void CanSerialize_returns_true_for_HttpError()
2417
{
@@ -43,13 +36,23 @@ public void SerializeError_serializes_httperror()
4336
{
4437
var textWriter = new StreamWriter(stream);
4538
var writer = new JsonTextWriter(textWriter);
46-
var error = new HttpError(new Exception("This is the exception message!"), true)
39+
40+
var mockInnerException = new Mock<Exception>(MockBehavior.Strict);
41+
mockInnerException.Setup(m => m.Message).Returns("Inner exception message");
42+
mockInnerException.Setup(m => m.StackTrace).Returns("Inner stack trace");
43+
44+
var outerException = new Exception("Outer exception message", mockInnerException.Object);
45+
46+
var error = new HttpError(outerException, true)
4747
{
48-
StackTrace = "Stack trace would go here"
48+
StackTrace = "Outer stack trace"
4949
};
5050
var jsonSerializer = new JsonSerializer();
5151

52-
var serializer = new ErrorSerializer(new TestErrorIdProvider());
52+
var mockIdProvider = new Mock<IErrorIdProvider>(MockBehavior.Strict);
53+
mockIdProvider.SetupSequence(p => p.GenerateId(It.IsAny<HttpError>())).Returns("OUTER-ID").Returns("INNER-ID");
54+
55+
var serializer = new ErrorSerializer(mockIdProvider.Object);
5356
serializer.SerializeError(error, stream, writer, jsonSerializer);
5457

5558
writer.Flush();

JSONAPI.Tests/Json/JsonApiMediaFormaterTests.cs

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using System.Collections.Generic;
1313
using System.IO;
1414
using System.Diagnostics;
15+
using Moq;
1516

1617
namespace JSONAPI.Tests.Json
1718
{
@@ -21,6 +22,7 @@ public class JsonApiMediaFormaterTests
2122
Author a;
2223
Post p, p2, p3, p4;
2324
Sample s1, s2;
25+
Tag t1, t2, t3;
2426

2527
private class MockErrorSerializer : IErrorSerializer
2628
{
@@ -54,6 +56,22 @@ public void SetupModels()
5456
Name = "Jason Hater",
5557
};
5658

59+
t1 = new Tag
60+
{
61+
Id = 1,
62+
Text = "Ember"
63+
};
64+
t2 = new Tag
65+
{
66+
Id = 2,
67+
Text = "React"
68+
};
69+
t3 = new Tag
70+
{
71+
Id = 3,
72+
Text = "Angular"
73+
};
74+
5775
p = new Post()
5876
{
5977
Id = 1,
@@ -234,7 +252,7 @@ public void SerializeArrayIntegrationTest()
234252

235253
[TestMethod]
236254
[DeploymentItem(@"Data\AttributeSerializationTest.json")]
237-
public void Serializes_attributes_properly()
255+
public void Serializes_attributes_properly()
238256
{
239257
// Arrang
240258
JsonApiFormatter formatter = new JsonApiFormatter(new PluralizationService());
@@ -250,6 +268,24 @@ public void Serializes_attributes_properly()
250268
Assert.AreEqual(expected, output.Trim());
251269
}
252270

271+
[TestMethod]
272+
[DeploymentItem(@"Data\ByteIdSerializationTest.json")]
273+
public void Serializes_byte_ids_properly()
274+
{
275+
// Arrang
276+
JsonApiFormatter formatter = new JsonApiFormatter(new PluralizationService());
277+
MemoryStream stream = new MemoryStream();
278+
279+
// Act
280+
formatter.WriteToStreamAsync(typeof(Tag), new[] { t1, t2, t3 }, stream, null, null);
281+
282+
// Assert
283+
string output = System.Text.Encoding.ASCII.GetString(stream.ToArray());
284+
Trace.WriteLine(output);
285+
var expected = JsonHelpers.MinifyJson(File.ReadAllText("ByteIdSerializationTest.json"));
286+
Assert.AreEqual(expected, output.Trim());
287+
}
288+
253289
[TestMethod]
254290
[DeploymentItem(@"Data\ReformatsRawJsonStringWithUnquotedKeys.json")]
255291
public void Reformats_raw_json_string_with_unquoted_keys()
@@ -315,20 +351,29 @@ public void SerializeErrorIntegrationTest()
315351
JsonApiFormatter formatter = new JSONAPI.Json.JsonApiFormatter(new JSONAPI.Core.PluralizationService());
316352
MemoryStream stream = new MemoryStream();
317353

318-
// Act
319-
var payload = new HttpError(new Exception("This is the exception message!"), true)
354+
var mockInnerException = new Mock<Exception>(MockBehavior.Strict);
355+
mockInnerException.Setup(m => m.Message).Returns("Inner exception message");
356+
mockInnerException.Setup(m => m.StackTrace).Returns("Inner stack trace");
357+
358+
var outerException = new Exception("Outer exception message", mockInnerException.Object);
359+
360+
var payload = new HttpError(outerException, true)
320361
{
321-
StackTrace = "Stack trace would go here"
362+
StackTrace = "Outer stack trace"
322363
};
364+
365+
// Act
323366
formatter.WriteToStreamAsync(typeof(HttpError), payload, stream, (System.Net.Http.HttpContent)null, (System.Net.TransportContext)null);
324367

325368
// Assert
326369
var expectedJson = File.ReadAllText("ErrorSerializerTest.json");
327370
var minifiedExpectedJson = JsonHelpers.MinifyJson(expectedJson);
328371
var output = System.Text.Encoding.ASCII.GetString(stream.ToArray());
329-
output = Regex.Replace(output,
330-
@"[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}",
331-
"TEST-ERROR-ID"); // We don't know what the GUID will be, so replace it
372+
373+
// We don't know what the GUIDs will be, so replace them
374+
var regex = new Regex(@"[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}");
375+
output = regex.Replace(output, "OUTER-ID", 1);
376+
output = regex.Replace(output, "INNER-ID", 1);
332377
output.Should().Be(minifiedExpectedJson);
333378
}
334379

JSONAPI.Tests/Models/Tag.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace JSONAPI.Tests.Models
8+
{
9+
class Tag
10+
{
11+
public byte Id { get; set; }
12+
public string Text { get; set; }
13+
}
14+
}

JSONAPI/Json/ErrorSerializer.cs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,33 @@ internal class ErrorSerializer : IErrorSerializer
1010
private class JsonApiError
1111
{
1212
[JsonProperty(PropertyName = "id")]
13-
public string Id { get; set; }
13+
public string Id { get; private set; }
1414

1515
[JsonProperty(PropertyName = "status")]
16-
public string Status { get; set; }
16+
public string Status { get; private set; }
1717

1818
[JsonProperty(PropertyName = "title")]
19-
public string Title { get; set; }
19+
public string Title { get; private set; }
2020

2121
[JsonProperty(PropertyName = "detail")]
22-
public string Detail { get; set; }
23-
24-
[JsonProperty(PropertyName = "inner")]
25-
public JsonApiError Inner { get; set; }
22+
public string Detail { get; private set; }
2623

2724
[JsonProperty(PropertyName = "stackTrace")]
28-
public string StackTrace { get; set; }
25+
public string StackTrace { get; private set; }
2926

30-
public JsonApiError(HttpError error)
27+
[JsonProperty(PropertyName = "inner")]
28+
public JsonApiError Inner { get; private set; }
29+
30+
public JsonApiError(HttpError error, IErrorIdProvider idProvider)
3131
{
32+
Id = idProvider.GenerateId(error);
3233
Title = error.ExceptionType ?? error.Message;
3334
Status = "500";
3435
Detail = error.ExceptionMessage ?? error.MessageDetail;
3536
StackTrace = error.StackTrace;
3637

3738
if (error.InnerException != null)
38-
Inner = new JsonApiError(error.InnerException);
39+
Inner = new JsonApiError(error.InnerException, idProvider);
3940
}
4041
}
4142

@@ -65,10 +66,7 @@ public void SerializeError(object error, Stream writeStream, JsonWriter writer,
6566
writer.WriteStartObject();
6667
writer.WritePropertyName("errors");
6768

68-
var jsonApiError = new JsonApiError(httpError)
69-
{
70-
Id = _errorIdProvider.GenerateId(httpError)
71-
};
69+
var jsonApiError = new JsonApiError(httpError, _errorIdProvider);
7270
serializer.Serialize(writer, new[] { jsonApiError });
7371

7472
writer.WriteEndObject();

JSONAPI/Json/JsonApiFormatter.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,8 @@ protected string GetValueForIdProperty(PropertyInfo idprop, object obj)
890890
return idprop.GetValue(obj).ToString();
891891
if (idprop.PropertyType == typeof(int))
892892
return ((int)idprop.GetValue(obj, null)).ToString();
893+
if (idprop.PropertyType == typeof(byte))
894+
return ((byte)idprop.GetValue(obj, null)).ToString();
893895
}
894896
return "NOIDCOMPUTABLE!";
895897
}

JSONAPI/Properties/AssemblyInfo.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
[assembly: InternalsVisibleTo("JSONAPI.Tests")]
2626
[assembly: InternalsVisibleTo("JSONAPI.EntityFramework.Tests")]
2727

28+
// This assembly is the default dynamic assembly generated Castle DynamicProxy,
29+
// used by Moq. Paste in a single line.
30+
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
31+
2832
// Version information for an assembly consists of the following four values:
2933
//
3034
// Major Version

0 commit comments

Comments
 (0)