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

[Saitej Kuralla] AB#1179754 added Quality factor capability #2

Merged
merged 1 commit into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,32 @@ public void CanWriteResult_ShouldReturnFalse_WhenAcceptHeaderIsInvalid()
Assert.False(result);
}

[Fact]
public void CanWriteResult_ShouldReturnTrue_WhenAcceptHeaderIsValidBasedOnQualityFactor()
{
// Arrange
var context = CreateOutputFormatterCanWriteContext("application/hal+json, application/json;q=0.667 , application/import+json; q=0.333");

// Act
var result = _formatter.CanWriteResult(context);

// Assert
Assert.True(result);
}

[Fact]
public void CanWriteResult_ShouldReturnFalse_WhenAcceptHeaderIsNotValidBasedOnQualityFactor()
{
// Arrange
var context = CreateOutputFormatterCanWriteContext("application/hal+json;q=0.667, application/json;q=1.0 , application/import+json; q=0.333");

// Act
var result = _formatter.CanWriteResult(context);

// Assert
Assert.False(result);
}

[Fact]
public async Task WriteAsync_ShouldSetContentTypeAndCallBaseMethods()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,33 @@
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
using System.Buffers;
using System.Net.Http.Headers;
using System.Text;

namespace AspnetCore.Hal.NewtonsoftHalJsonFormatter
{
internal class HalJsonOutputFormatter(JsonSerializerSettings serializerSettings, ArrayPool<char> charPool, MvcOptions options, MvcNewtonsoftJsonOptions value) : NewtonsoftJsonOutputFormatter(serializerSettings, charPool, options, value)
{
private static readonly MediaTypeHeaderValue AcceptableMimeType = MediaTypeHeaderValue.Parse("application/hal+json");
private static readonly Microsoft.Net.Http.Headers.MediaTypeHeaderValue AcceptableMimeType = Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/hal+json");

public override bool CanWriteResult(OutputFormatterCanWriteContext context)
{
if (!context.HttpContext.Request.Headers.TryGetValue(HeaderNames.Accept, out var acceptHeader))
{
return false;
}
var hasSupportedHeader = context.HttpContext.Request.Headers.Accept
.Select(a => MediaTypeHeaderValue.Parse(new StringSegment(a)))
.Any(a => a.IsSubsetOf(AcceptableMimeType));
var acceptHeaders = context.HttpContext.Request.Headers["Accept"].ToString().Split(',')
.Select(h => MediaTypeWithQualityHeaderValue.Parse(h.Trim()))
.OrderByDescending(h => h.Quality ?? 1.0) // Sort by quality factor in descending order
.ToList();


// Check if the top value matches the acceptable MIME type
var qualityHeader = acceptHeaders.FirstOrDefault();

var hasSupportedHeader = qualityHeader != null &&
Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse(new StringSegment(qualityHeader.MediaType))
.IsSubsetOf(Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse(new StringSegment(AcceptableMimeType.ToString())));
var provider = context.HttpContext.RequestServices;
var cfg = provider.GetService<IProvideHalTypeConfiguration>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,31 @@ public void CanWriteResult_ShouldReturnFalse_WhenAcceptHeaderIsInvalid()
// Assert
Assert.False(result);
}
[Fact]
public void CanWriteResult_ShouldReturnTrue_WhenAcceptHeaderIsValidBasedOnQualityFactor()
{
// Arrange
var context = CreateOutputFormatterCanWriteContext("application/hal+json, application/json;q=0.667 , application/import+json; q=0.333");

// Act
var result = _formatter.CanWriteResult(context);

// Assert
Assert.True(result);
}

[Fact]
public void CanWriteResult_ShouldReturnFalse_WhenAcceptHeaderIsNotValidBasedOnQualityFactor()
{
// Arrange
var context = CreateOutputFormatterCanWriteContext("application/hal+json;q=0.667, application/json;q=1.0 , application/import+json; q=0.333");

// Act
var result = _formatter.CanWriteResult(context);

// Assert
Assert.False(result);
}

[Fact]
public async Task WriteAsync_ShouldSetContentTypeAndCallBaseMethods()
Expand Down
19 changes: 15 additions & 4 deletions src/AspnetCore.Hal.TextHalJsonFormatter/HalJsonOutputFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
using AspnetCore.Hal.Processors;
using Microsoft.Net.Http.Headers;
using Microsoft.Extensions.Primitives;
using System.Net.Http.Headers;


namespace AspnetCore.Hal.SystemTextHalJsonFormatter;

internal class HalJsonOutputFormatter : SystemTextJsonOutputFormatter
{
private static readonly MediaTypeHeaderValue AcceptableMimeType = MediaTypeHeaderValue.Parse("application/hal+json");
private static readonly Microsoft.Net.Http.Headers.MediaTypeHeaderValue AcceptableMimeType = Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/hal+json");

public HalJsonOutputFormatter(JsonSerializerOptions jsonSerializerOptions) : base(jsonSerializerOptions)
{
Expand All @@ -29,9 +30,19 @@ public override bool CanWriteResult(OutputFormatterCanWriteContext context)
{
return false;
}
var hasSupportedHeader = context.HttpContext.Request.Headers.Accept
.Select(a => MediaTypeHeaderValue.Parse(new StringSegment(a)))
.Any(a => a.IsSubsetOf(AcceptableMimeType));

var acceptHeaders = context.HttpContext.Request.Headers["Accept"].ToString().Split(',')
.Select(h => MediaTypeWithQualityHeaderValue.Parse(h.Trim()))
.OrderByDescending(h => h.Quality ?? 1.0) // Sort by quality factor in descending order
.ToList();


// Check if the top value matches the acceptable MIME type
var qualityHeader = acceptHeaders.FirstOrDefault();

var hasSupportedHeader = qualityHeader != null &&
Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse(new StringSegment(qualityHeader.MediaType))
.IsSubsetOf(Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse(new StringSegment(AcceptableMimeType.ToString())));

var provider = context.HttpContext.RequestServices;
var cfg = provider.GetService<IProvideHalTypeConfiguration>();
Expand Down
Loading