Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve default IsValidResponseToDeserialize implementation #560

Merged
Merged
14 changes: 11 additions & 3 deletions src/GraphQL.Client/GraphQLHttpClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,17 @@ public class GraphQLHttpClientOptions
/// Note that compatible to the draft graphql-over-http spec GraphQL Server MAY return 4xx status codes (401/403, etc.)
/// with well-formed GraphQL response containing errors collection.
/// </summary>
public Func<HttpResponseMessage, bool> IsValidResponseToDeserialize { get; set; } = r =>
// Why not application/json? See https://github.com/graphql/graphql-over-http/blob/main/spec/GraphQLOverHTTP.md#processing-the-response
r.IsSuccessStatusCode || r.StatusCode == HttpStatusCode.BadRequest || r.Content.Headers.ContentType?.MediaType == "application/graphql+json";
public Func<HttpResponseMessage, bool> IsValidResponseToDeserialize { get; set; } = DefaultIsValidResponseToDeserialize;

private static readonly IReadOnlyCollection<string> _acceptedResponseContentTypes = new[] { "application/graphql+json", "application/json", "application/graphql-response+json" };

public static bool DefaultIsValidResponseToDeserialize(HttpResponseMessage r)
{
if (r.Content.Headers.ContentType?.MediaType != null && !_acceptedResponseContentTypes.Contains(r.Content.Headers.ContentType.MediaType))
return false;

return r.IsSuccessStatusCode || r.StatusCode == HttpStatusCode.BadRequest;
}

/// <summary>
/// This callback is called after successfully establishing a websocket connection but before any regular request is made.
Expand Down
28 changes: 28 additions & 0 deletions tests/GraphQL.Client.Serializer.Tests/DefaultValidationTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Net;
using System.Net.Http.Headers;
using FluentAssertions;
using GraphQL.Client.Http;
using Xunit;

namespace GraphQL.Client.Serializer.Tests;

public class DefaultValidationTest
{
[Theory]
[InlineData(HttpStatusCode.OK, "application/json", true)]
[InlineData(HttpStatusCode.OK, "application/graphql-response+json", true)]
[InlineData(HttpStatusCode.BadRequest, "application/json", true)]
[InlineData(HttpStatusCode.BadRequest, "text/html", false)]
[InlineData(HttpStatusCode.OK, "text/html", false)]
[InlineData(HttpStatusCode.Forbidden, "text/html", false)]
[InlineData(HttpStatusCode.Forbidden, "application/json", false)]
public void IsValidResponse_OkJson_True(HttpStatusCode statusCode, string mediaType, bool expectedResult)
{
var response = new HttpResponseMessage(statusCode);
response.Content.Headers.ContentType = new MediaTypeHeaderValue(mediaType);

bool isValid = new GraphQLHttpClientOptions().IsValidResponseToDeserialize(response);

isValid.Should().Be(expectedResult);
}
}