Skip to content

Commit f1a5bf8

Browse files
mikocotsungam3r
andauthored
Improve default IsValidResponseToDeserialize implementation (#560)
* change default implementation of response validation method to ensure correct response content type * add tests for the default validation method * remove unnecessary comments Co-authored-by: Ivan Maximov <[email protected]> * accepted response types private, formatting * make DefaultIsValidResponseToDeserialize publicly accessible Co-authored-by: Ivan Maximov <[email protected]> * AcceptedResponseContentTypes as static field --------- Co-authored-by: Ivan Maximov <[email protected]>
1 parent 8210ac3 commit f1a5bf8

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/GraphQL.Client/GraphQLHttpClientOptions.cs

+11-3
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,17 @@ public class GraphQLHttpClientOptions
6161
/// Note that compatible to the draft graphql-over-http spec GraphQL Server MAY return 4xx status codes (401/403, etc.)
6262
/// with well-formed GraphQL response containing errors collection.
6363
/// </summary>
64-
public Func<HttpResponseMessage, bool> IsValidResponseToDeserialize { get; set; } = r =>
65-
// Why not application/json? See https://github.com/graphql/graphql-over-http/blob/main/spec/GraphQLOverHTTP.md#processing-the-response
66-
r.IsSuccessStatusCode || r.StatusCode == HttpStatusCode.BadRequest || r.Content.Headers.ContentType?.MediaType == "application/graphql+json";
64+
public Func<HttpResponseMessage, bool> IsValidResponseToDeserialize { get; set; } = DefaultIsValidResponseToDeserialize;
65+
66+
private static readonly IReadOnlyCollection<string> _acceptedResponseContentTypes = new[] { "application/graphql+json", "application/json", "application/graphql-response+json" };
67+
68+
public static bool DefaultIsValidResponseToDeserialize(HttpResponseMessage r)
69+
{
70+
if (r.Content.Headers.ContentType?.MediaType != null && !_acceptedResponseContentTypes.Contains(r.Content.Headers.ContentType.MediaType))
71+
return false;
72+
73+
return r.IsSuccessStatusCode || r.StatusCode == HttpStatusCode.BadRequest;
74+
}
6775

6876
/// <summary>
6977
/// This callback is called after successfully establishing a websocket connection but before any regular request is made.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System.Net;
2+
using System.Net.Http.Headers;
3+
using FluentAssertions;
4+
using GraphQL.Client.Http;
5+
using Xunit;
6+
7+
namespace GraphQL.Client.Serializer.Tests;
8+
9+
public class DefaultValidationTest
10+
{
11+
[Theory]
12+
[InlineData(HttpStatusCode.OK, "application/json", true)]
13+
[InlineData(HttpStatusCode.OK, "application/graphql-response+json", true)]
14+
[InlineData(HttpStatusCode.BadRequest, "application/json", true)]
15+
[InlineData(HttpStatusCode.BadRequest, "text/html", false)]
16+
[InlineData(HttpStatusCode.OK, "text/html", false)]
17+
[InlineData(HttpStatusCode.Forbidden, "text/html", false)]
18+
[InlineData(HttpStatusCode.Forbidden, "application/json", false)]
19+
public void IsValidResponse_OkJson_True(HttpStatusCode statusCode, string mediaType, bool expectedResult)
20+
{
21+
var response = new HttpResponseMessage(statusCode);
22+
response.Content.Headers.ContentType = new MediaTypeHeaderValue(mediaType);
23+
24+
bool isValid = new GraphQLHttpClientOptions().IsValidResponseToDeserialize(response);
25+
26+
isValid.Should().Be(expectedResult);
27+
}
28+
}

0 commit comments

Comments
 (0)