@@ -17,63 +17,126 @@ namespace Tesla.NET.HttpHandlers
1717 using Newtonsoft . Json . Linq ;
1818 using Xunit . Abstractions ;
1919
20+ /// <summary>
21+ /// A test <see cref="HttpMessageHandler"/> that records requests and returned fixed responses.
22+ /// </summary>
2023 public class TestHttpHandler : HttpMessageHandler
2124 {
2225 private readonly ITestOutputHelper _output ;
2326
2427 private int _responseIndex ;
2528
29+ /// <summary>
30+ /// Initializes a new instance of the <see cref="TestHttpHandler"/> class.
31+ /// </summary>
32+ /// <param name="output">The <see cref="ITestOutputHelper"/>.</param>
2633 public TestHttpHandler ( ITestOutputHelper output )
2734 {
2835 _output = output ?? throw new ArgumentNullException ( nameof ( output ) ) ;
2936 }
3037
38+ /// <summary>
39+ /// Gets or sets the last received request.
40+ /// </summary>
3141 public HttpRequestMessage Request
3242 {
33- get => Requests . Count == 0 ? null : Requests [ Requests . Count - 1 ] ;
43+ get
44+ {
45+ if ( Requests . Count == 0 )
46+ throw new InvalidOperationException ( "There are no requests to return." ) ;
47+
48+ return Requests [ Requests . Count - 1 ] ;
49+ }
50+
3451 set
3552 {
53+ if ( value is null )
54+ throw new ArgumentNullException ( nameof ( value ) ) ;
55+
3656 Requests . Clear ( ) ;
3757 Requests . Add ( value ) ;
3858 }
3959 }
4060
61+ /// <summary>
62+ /// Gets the list of received requests.
63+ /// </summary>
4164 public List < HttpRequestMessage > Requests { get ; } = new List < HttpRequestMessage > ( 1 ) ;
4265
66+ /// <summary>
67+ /// Gets the list of fixed responses.
68+ /// </summary>
4369 public List < HttpResponseMessage > Responses { get ; } = new List < HttpResponseMessage > ( 1 ) ;
4470
45- public List < string > RequestContents { get ; } = new List < string > ( 1 ) ;
71+ /// <summary>
72+ /// Gets the list of request contents.
73+ /// </summary>
74+ public List < string ? > RequestContents { get ; } = new List < string ? > ( 1 ) ;
4675
76+ /// <summary>
77+ /// Gets or sets the last fixed response.
78+ /// </summary>
4779 public HttpResponseMessage Response
4880 {
49- get => Responses . Count == 0 ? null : Responses [ Responses . Count - 1 ] ;
81+ get
82+ {
83+ if ( Responses . Count == 0 )
84+ throw new InvalidOperationException ( "There are no responses to return." ) ;
85+
86+ return Responses [ Responses . Count - 1 ] ;
87+ }
88+
5089 set
5190 {
91+ if ( value is null )
92+ throw new ArgumentNullException ( nameof ( value ) ) ;
93+
5294 _responseIndex = 0 ;
5395 Responses . Clear ( ) ;
5496 Responses . Add ( value ) ;
5597 }
5698 }
5799
58- public Func < HttpRequestMessage , Task < HttpRequestMessage > > OnSendingRequest { get ; set ; }
100+ /// <summary>
101+ /// Get or sets a function to intercept request sending.
102+ /// </summary>
103+ public Func < HttpRequestMessage , Task < HttpRequestMessage > > ? OnSendingRequest { get ; set ; }
59104
105+ /// <summary>
106+ /// Sets the fixed response with the specified <paramref name="code"/>.
107+ /// </summary>
108+ /// <param name="code">The response <see cref="HttpStatusCode"/> to use.</param>
60109 public void SetResponse ( HttpStatusCode code ) => SetResponseContent ( null , code ) ;
61110
62- public void SetResponseContent ( object content , HttpStatusCode code = HttpStatusCode . OK )
111+ /// <summary>
112+ /// Sets the fixed response with the specified <paramref name="content"/> and <paramref name="code"/>.
113+ /// </summary>
114+ /// <param name="content">The response content to use.</param>
115+ /// <param name="code">The response <see cref="HttpStatusCode"/> to use.</param>
116+ public void SetResponseContent ( object ? content , HttpStatusCode code = HttpStatusCode . OK )
63117 {
64118 Response = CreateResponse ( content , code ) ;
65119 }
66120
121+ /// <summary>
122+ /// Adds the fixed response with the specified <paramref name="content"/> and <paramref name="code"/>.
123+ /// </summary>
124+ /// <param name="content">The response content to use.</param>
125+ /// <param name="code">The response <see cref="HttpStatusCode"/> to use.</param>
67126 public void AddResponseContent ( object content , HttpStatusCode code = HttpStatusCode . OK )
68127 {
69128 Responses . Add ( CreateResponse ( content , code ) ) ;
70129 }
71130
131+ /// <inheritdoc />
72132 protected override async Task < HttpResponseMessage > SendAsync (
73133 HttpRequestMessage request ,
74134 CancellationToken cancellationToken )
75135 {
76- string requestContent = await GetStringContent ( request . Content ) . ConfigureAwait ( false ) ;
136+ if ( request is null )
137+ throw new ArgumentNullException ( nameof ( request ) ) ;
138+
139+ string ? requestContent = await GetStringContent ( request . Content ) . ConfigureAwait ( false ) ;
77140 RequestContents . Add ( requestContent ) ;
78141
79142 _output . WriteLine ( $ "Started { request . Method } '{ request . RequestUri } '") ;
@@ -97,15 +160,15 @@ protected override async Task<HttpResponseMessage> SendAsync(
97160 HttpResponseMessage responseMessage =
98161 _responseIndex < Responses . Count
99162 ? Responses [ _responseIndex ++ ]
100- : CreateResponse ( string . Empty ) ;
163+ : CreateResponse ( "{}" ) ;
101164
102165 responseMessage . RequestMessage = request ;
103166
104167 _output . WriteLine (
105168 $ "Completed { request . Method } '{ request . RequestUri } ' " +
106169 $ "with { responseMessage . StatusCode : G} ({ responseMessage . StatusCode : D} )") ;
107170
108- string responseContent = await GetStringContent ( responseMessage . Content ) . ConfigureAwait ( false ) ;
171+ string ? responseContent = await GetStringContent ( responseMessage . Content ) . ConfigureAwait ( false ) ;
109172 if ( responseContent != null )
110173 {
111174 _output . WriteLine ( responseContent ) ;
@@ -114,15 +177,15 @@ protected override async Task<HttpResponseMessage> SendAsync(
114177 return responseMessage ;
115178 }
116179
117- private static async Task < string > GetStringContent ( HttpContent content )
180+ private static async Task < string ? > GetStringContent ( HttpContent content )
118181 {
119- if ( content == null )
182+ if ( content is null )
120183 return null ;
121184
122185 string contentData ;
123186 if ( content is ForcedAsyncStreamContent delayedContent )
124187 {
125- using ( var s = new StreamReader ( delayedContent . Stream , Encoding . UTF8 , true , 10240 , leaveOpen : true ) )
188+ using ( var s = new StreamReader ( delayedContent . Stream , Encoding . UTF8 , true , 10240 , leaveOpen : true ) )
126189 {
127190 contentData = s . ReadToEnd ( ) ;
128191 }
@@ -134,7 +197,8 @@ private static async Task<string> GetStringContent(HttpContent content)
134197 contentData = await content . ReadAsStringAsync ( ) . ConfigureAwait ( false ) ;
135198 }
136199
137- bool ? isJson = content . Headers ? . ContentType ? . ToString ( ) . Equals ( "application/json" ) ;
200+ bool ? isJson = content . Headers ? . ContentType ? . ToString ( )
201+ . Equals ( "application/json" , StringComparison . OrdinalIgnoreCase ) ;
138202 if ( isJson . GetValueOrDefault ( ) )
139203 {
140204 contentData = JToken . Parse ( contentData ) . ToString ( Formatting . Indented ) ;
@@ -143,9 +207,9 @@ private static async Task<string> GetStringContent(HttpContent content)
143207 return contentData ;
144208 }
145209
146- private static HttpResponseMessage CreateResponse ( object content , HttpStatusCode code = HttpStatusCode . OK )
210+ private static HttpResponseMessage CreateResponse ( object ? content , HttpStatusCode code = HttpStatusCode . OK )
147211 {
148- if ( content == null )
212+ if ( content is null )
149213 {
150214 return new HttpResponseMessage ( code ) ;
151215 }
@@ -166,7 +230,7 @@ private static HttpResponseMessage CreateResponse(object content, HttpStatusCode
166230 Headers =
167231 {
168232 ContentType = new MediaTypeHeaderValue ( "application/json" ) ,
169- }
233+ } ,
170234 } ;
171235
172236 return new HttpResponseMessage ( code )
0 commit comments