-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApplicationBuilderMiddlewareTests.ProblemDetail.cs
More file actions
205 lines (168 loc) · 8.77 KB
/
ApplicationBuilderMiddlewareTests.ProblemDetail.cs
File metadata and controls
205 lines (168 loc) · 8.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
// -------------------------------------------------------
// Copyright (c) BlazorFocused All rights reserved.
// Licensed under the MIT License
// -------------------------------------------------------
using BlazorFocused.Exceptions.Middleware.ApplicationBuilder;
using BlazorFocused.Exceptions.Middleware.ExceptionBuilder;
using Bogus;
using FluentAssertions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Moq;
using System.Net;
namespace BlazorFocused.Exceptions.Middleware.Test.ApplicationBuilder;
public partial class ApplicationBuilderMiddlewareTests
{
[Theory]
[MemberData(nameof(Exceptions))]
public async Task Invoke_ShouldReturnProblemDetailsNoConfiguration(Exception thrownException)
{
using MemoryStream memoryStream =
GenerateHttpContext(out string expectedInstance, out HttpContext httpContext);
IOptionsMonitor<ExceptionsMiddlewareBuilderOptions> optionsMonitor = default;
var exceptionsMiddlewareOptions = new ExceptionsMiddlewareOptions();
requestDelegateMock.Setup(request =>
request.Invoke(httpContext))
.ThrowsAsync(thrownException);
Exception actualException =
await Record.ExceptionAsync(() =>
applicationBuilderMiddleware.Invoke(
httpContext,
Options.Create(exceptionsMiddlewareOptions),
optionsMonitor,
NullLogger<ApplicationBuilderMiddleware>.Instance));
ProblemDetails actualErrorResponse = await GetErrorResponseFromBody<ProblemDetails>(memoryStream);
// Should be null since error is caught
actualException.Should().BeNull();
Assert.Equal(exceptionsMiddlewareOptions.DefaultErrorMessage, actualErrorResponse.Detail);
Assert.Equal(expectedInstance, actualErrorResponse.Instance);
Assert.Equal((int)exceptionsMiddlewareOptions.DefaultErrorStatusCode, actualErrorResponse.Status);
Assert.Equal((int)exceptionsMiddlewareOptions.DefaultErrorStatusCode, httpContext.Response.StatusCode);
Assert.Equal(thrownException.GetType().Name, actualErrorResponse.Type);
}
[Theory]
[MemberData(nameof(ExceptionsWithStatusCode))]
public async Task Invoke_ShouldReturnProblemDetailsWithDefaultMessage(Exception thrownException,
HttpStatusCode expectedStatusCode)
{
using MemoryStream memoryStream =
GenerateHttpContext(out string expectedInstance, out HttpContext httpContext);
string expectedMessage = new Faker().Lorem.Sentence();
var configuredExceptionOptions = new ExceptionsMiddlewareBuilderOptions
{
ExceptionType = thrownException.GetType(),
HttpStatusCode = expectedStatusCode,
DefaultMessage = expectedMessage
};
IOptionsMonitor<ExceptionsMiddlewareBuilderOptions> optionsMonitor =
GenerateOptionsMonitor(thrownException.GetType().AssemblyQualifiedName, configuredExceptionOptions);
requestDelegateMock.Setup(request =>
request.Invoke(httpContext))
.ThrowsAsync(thrownException);
Exception actualException =
await Record.ExceptionAsync(() =>
applicationBuilderMiddleware.Invoke(
httpContext,
Options.Create(new ExceptionsMiddlewareOptions()),
optionsMonitor,
NullLogger<ApplicationBuilderMiddleware>.Instance));
ProblemDetails actualErrorResponse = await GetErrorResponseFromBody<ProblemDetails>(memoryStream);
// Should be null since error is caught
actualException.Should().BeNull();
Assert.Equal(expectedMessage, actualErrorResponse.Detail);
Assert.Equal(expectedInstance, actualErrorResponse.Instance);
Assert.Equal((int)expectedStatusCode, actualErrorResponse.Status);
Assert.Equal((int)expectedStatusCode, httpContext.Response.StatusCode);
Assert.Equal(thrownException.GetType().Name, actualErrorResponse.Type);
}
[Fact]
public async Task Invoke_ShouldReturnProblemDetailsWithConfiguredMessage()
{
using MemoryStream memoryStream =
GenerateHttpContext(out string expectedInstance, out HttpContext httpContext);
string expectedMessage = new Faker().Lorem.Sentence();
string exceptionMessage = new Faker().Lorem.Sentence();
var thrownException = new AccessViolationException(exceptionMessage);
HttpStatusCode expectedStatusCode = HttpStatusCode.SwitchingProtocols;
var configuredExceptionOptions = new ExceptionsMiddlewareBuilderOptions
{
ExceptionType = thrownException.GetType(),
ExceptionResponseResolver =
new ExceptionResponseResolver<Exception>((httpContext, exception) =>
{
return new ExceptionsMiddlewareResponse
{
ErrorMessage = expectedMessage,
HttpStatusCode = expectedStatusCode
};
})
};
IOptionsMonitor<ExceptionsMiddlewareBuilderOptions> optionsMonitor =
GenerateOptionsMonitor(thrownException.GetType().AssemblyQualifiedName, configuredExceptionOptions);
requestDelegateMock.Setup(request =>
request.Invoke(httpContext))
.ThrowsAsync(thrownException);
Exception actualException =
await Record.ExceptionAsync(() =>
applicationBuilderMiddleware.Invoke(
httpContext,
Options.Create(new ExceptionsMiddlewareOptions()),
optionsMonitor,
NullLogger<ApplicationBuilderMiddleware>.Instance));
ProblemDetails actualErrorResponse = await GetErrorResponseFromBody<ProblemDetails>(memoryStream);
// Should be null since error is caught
actualException.Should().BeNull();
Assert.Equal(expectedMessage, actualErrorResponse.Detail);
Assert.NotEqual(exceptionMessage, actualErrorResponse.Detail);
Assert.Equal(expectedInstance, actualErrorResponse.Instance);
Assert.Equal((int)expectedStatusCode, actualErrorResponse.Status);
Assert.Equal((int)expectedStatusCode, httpContext.Response.StatusCode);
Assert.Equal(thrownException.GetType().Name, actualErrorResponse.Type);
}
[Fact]
public async Task Invoke_ShouldAllowProblemDetailsOverride()
{
string exceptionMessage = new Faker().Lorem.Sentence();
string expectedType = "Test Override 1";
string overrideInstance = " - Test Override 2";
string overrideMessage = "Test Override 3 ";
string expectedDetail = overrideMessage + exceptionMessage;
int expectedStatusCode = (int)HttpStatusCode.GatewayTimeout;
var thrownException = new ApplicationException(exceptionMessage);
using MemoryStream memoryStream =
GenerateHttpContext(out string initialInstance, out HttpContext httpContext);
string expectedInstance = initialInstance + overrideInstance;
IOptionsMonitor<ExceptionsMiddlewareBuilderOptions> optionsMonitor = null;
var exceptionsMiddlewareOptions = new ExceptionsMiddlewareOptions
{
ConfigureProblemDetails = (httpContext, exceptionMessage, problemDetails) =>
{
problemDetails.Detail = overrideMessage + exceptionMessage.Message;
problemDetails.Instance = httpContext.Request.Path + httpContext.Request.QueryString + overrideInstance;
problemDetails.Status = expectedStatusCode;
problemDetails.Type = expectedType;
return problemDetails;
}
};
requestDelegateMock.Setup(request =>
request.Invoke(httpContext))
.ThrowsAsync(thrownException);
Exception actualException =
await Record.ExceptionAsync(() =>
applicationBuilderMiddleware.Invoke(
httpContext,
Options.Create(exceptionsMiddlewareOptions),
optionsMonitor,
NullLogger<ApplicationBuilderMiddleware>.Instance));
ProblemDetails actualErrorResponse = await GetErrorResponseFromBody<ProblemDetails>(memoryStream);
// Should be null since error is caught
actualException.Should().BeNull();
Assert.Equal(expectedDetail, actualErrorResponse.Detail);
Assert.Equal(expectedInstance, actualErrorResponse.Instance);
Assert.Equal(expectedStatusCode, actualErrorResponse.Status);
Assert.Equal(expectedType, actualErrorResponse.Type);
Assert.NotEqual(expectedStatusCode, httpContext.Response.StatusCode);
}
}