Skip to content

v2.1.5 #168

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

Merged
merged 2 commits into from
Sep 23, 2017
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
2 changes: 1 addition & 1 deletion src/JsonApiDotNetCore/JsonApiDotNetCore.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<VersionPrefix>2.1.4</VersionPrefix>
<VersionPrefix>2.1.5</VersionPrefix>
<TargetFrameworks>netstandard1.6</TargetFrameworks>
<AssemblyName>JsonApiDotNetCore</AssemblyName>
<PackageId>JsonApiDotNetCore</PackageId>
Expand Down
9 changes: 0 additions & 9 deletions src/JsonApiDotNetCore/Services/IQueryAccessor.cs

This file was deleted.

35 changes: 27 additions & 8 deletions src/JsonApiDotNetCore/Services/QueryAccessor.cs
Original file line number Diff line number Diff line change
@@ -1,43 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using JsonApiDotNetCore.Internal;
using Microsoft.Extensions.Logging;

namespace JsonApiDotNetCore.Services
{
public interface IQueryAccessor
{
bool TryGetValue<T>(string key, out T value);

/// <summary>
/// Gets the query value and throws a if it is not present.
/// If the exception is not caught, the middleware will return an HTTP 422 response.
/// </summary>
/// <exception cref="JsonApiException" />
T GetRequired<T>(string key);
}

public class QueryAccessor : IQueryAccessor
{
private readonly IJsonApiContext _jsonApiContext;
private readonly ILogger<QueryAccessor> _logger;

public QueryAccessor(
IJsonApiContext jsonApiContext,
ILoggerFactory loggerFactory)
IJsonApiContext jsonApiContext,
ILogger<QueryAccessor> logger)
{
_jsonApiContext = jsonApiContext;
_logger = loggerFactory.CreateLogger<QueryAccessor>();
_logger = logger;
}

public T GetRequired<T>(string key)
{
if (TryGetValue<T>(key, out T result) == false)
throw new JsonApiException(422, $"'{key}' is not a valid '{typeof(T).Name}' value for query parameter {key}");

return result;
}

public bool TryGetValue<T>(string key, out T value)
{
value = default(T);

var stringValue = GetFilterValue(key);
if(stringValue == null)
var stringValue = GetFilterValue(key);
if (stringValue == null)
{
_logger.LogInformation($"'{key}' was not found in the query collection");
return false;
}

try
{
value = TypeHelper.ConvertType<T>(stringValue);
return true;
}
catch (FormatException)
{
_logger.LogInformation($"'{value}' is not a valid guid value for query parameter {key}");
_logger.LogInformation($"'{value}' is not a valid '{typeof(T).Name}' value for query parameter {key}");
return false;
}
}
Expand Down
61 changes: 58 additions & 3 deletions test/UnitTests/Services/QueryAccessorTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using JsonApiDotNetCore.Internal;
using JsonApiDotNetCore.Internal.Query;
using JsonApiDotNetCore.Services;
using Microsoft.AspNetCore.Http;
Expand All @@ -13,13 +14,13 @@ namespace UnitTests.Services
public class QueryAccessorTests
{
private readonly Mock<IJsonApiContext> _contextMock;
private readonly Mock<ILoggerFactory> _loggerMock;
private readonly Mock<ILogger<QueryAccessor>> _loggerMock;
private readonly Mock<IQueryCollection> _queryMock;

public QueryAccessorTests()
{
_contextMock = new Mock<IJsonApiContext>();
_loggerMock = new Mock<ILoggerFactory>();
_loggerMock = new Mock<ILogger<QueryAccessor>>();
_queryMock = new Mock<IQueryCollection>();
}

Expand All @@ -34,7 +35,7 @@ public void Can_Get_Guid_QueryValue()
var query = new Dictionary<string, StringValues> {
{ filterQuery, value.ToString() }
};

_queryMock.Setup(q => q.GetEnumerator()).Returns(query.GetEnumerator());

var querySet = new QuerySet(_contextMock.Object, _queryMock.Object);
Expand All @@ -50,5 +51,59 @@ public void Can_Get_Guid_QueryValue()
Assert.True(success);
Assert.Equal(value, result);
}

[Fact]
public void GetRequired_Throws_If_Not_Present()
{
// arrange
const string key = "some-id";
var filterQuery = $"filter[{key}]";
var value = Guid.NewGuid();

var query = new Dictionary<string, StringValues> {
{ filterQuery, value.ToString() }
};

_queryMock.Setup(q => q.GetEnumerator()).Returns(query.GetEnumerator());

var querySet = new QuerySet(_contextMock.Object, _queryMock.Object);
_contextMock.Setup(c => c.QuerySet)
.Returns(querySet);

var service = new QueryAccessor(_contextMock.Object, _loggerMock.Object);

// act
var exception = Assert.Throws<JsonApiException>(() => service.GetRequired<Guid>("Invalid"));

// assert
Assert.Equal(422, exception.GetStatusCode());
}

[Fact]
public void GetRequired_Does_Not_Throw_If_Present()
{
// arrange
const string key = "some-id";
var filterQuery = $"filter[{key}]";
var value = Guid.NewGuid();

var query = new Dictionary<string, StringValues> {
{ filterQuery, value.ToString() }
};

_queryMock.Setup(q => q.GetEnumerator()).Returns(query.GetEnumerator());

var querySet = new QuerySet(_contextMock.Object, _queryMock.Object);
_contextMock.Setup(c => c.QuerySet)
.Returns(querySet);

var service = new QueryAccessor(_contextMock.Object, _loggerMock.Object);

// act
var result = service.GetRequired<Guid>("SomeId");

// assert
Assert.Equal(value, result);
}
}
}