Skip to content

Commit

Permalink
FIX: Corrected CORS content-type header (#46)
Browse files Browse the repository at this point in the history
## Description
FIX: Corrected CORS configuration to include `Content-Type` header by
default.
REFACTOR: Rename `Page.Results` to `Page.Items` for better description.

## Related Issue

## Motivation and Context
- When accessing the API from some webapps, it occurs the problem of
CORS being rejected because `Content-Type` is not included by default in
the API's CORS configuration. And since it's so easy for this to become
a requirement in almost any webapp, then it's better to include it by
default.
- The `Page` class contains a list of items being paged called
`Results`. This sometimes generates confusion and it's a better
description if it would be renamed to `Items` (`Page.Items`)

## How Has This Been Tested?
Unit tests updated accordingly for the `Page.Items` change.
Manual testing for the CORS configuration.

## Screenshots (if appropriate):

## Types of changes
- [X] Bug fix (non-breaking change which fixes an issue)
- [X] Refactor
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)

## Checklist:
- [X] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [X] I have read the **CONTRIBUTING** document.
- [X] I have added tests to cover my changes.
- [X] All new and existing tests passed.
  • Loading branch information
CesarD committed Jun 14, 2023
1 parent a6dfaa8 commit 3596c65
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"CorsPolicies": [
{
"Name": "Default",
"Origins": [ "http://localhost:3000" ],
"Headers": [ "Authorization" ],
"Origins": [ "http://localhost:4200" ],
"Headers": [ "Authorization", "Content-Type" ],
"Methods": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ]
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public async Task GetCompanyPageWithoutParamsSucceeds(List<Domain.Model.Company>

result.Should().NotBeNull();
result!.Pager.Count.Should().Be(companies.Count);
result.Results
result.Items
.Should()
.HaveCount(companies.Count).And
.Contain(x => companies.Any(c => c.Name == x.Name)).And
Expand All @@ -58,7 +58,7 @@ public async Task GetCompanyPageWithParamsSucceeds(List<Domain.Model.Company> co

result.Should().NotBeNull();
result!.Pager.Count.Should().Be(companiesSet.Count);
result.Results
result.Items
.Should()
.HaveCount(companiesSet.Count).And
.Contain(x => companiesSet.Any(c => c.Name == x.Name)).And
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public void CreateNewPageSucceeds(List<string> results, int offset, int limit, l
var sut = new Page<string>(results, offset, limit, count);

sut.Pager.Should().NotBeNull().And.BeEquivalentTo(new Pager(offset, limit, count));
sut.Results.Should().OnlyContain(s => results.Contains(s));
sut.Items.Should().OnlyContain(s => results.Contains(s));
}

[Trait("Common Domain Entities", "Pager Entity")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ public record Page<T>
{
/// <summary>
/// </summary>
/// <param name="results">Results subset</param>
/// <param name="items">Items subset</param>
/// <param name="offset">Record from where to start paging</param>
/// <param name="limit">Amount of items to page</param>
/// <param name="count">Total amount of items</param>
public Page(IEnumerable<T> results, int offset, int limit, long count)
public Page(IEnumerable<T> items, int offset, int limit, long count)
{
Results = results.ToList();
Items = items.ToList();
Pager = new Pager(offset, limit, count);
}

Expand All @@ -19,9 +19,9 @@ public Page(IEnumerable<T> results, int offset, int limit, long count)
/// </summary>
public Pager Pager { get; }
/// <summary>
/// Paged results
/// Paged items
/// </summary>
public IReadOnlyList<T> Results { get; }
public IReadOnlyList<T> Items { get; }
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,40 +53,37 @@ private static IOrderedQueryable<T> GetOrderedQuery<T>(this IQueryable<T> source
{
var bodyExpression = (MemberExpression)(expression.Body.NodeType == ExpressionType.Convert ? ((UnaryExpression)expression.Body).Operand : expression.Body);
var sortLambda = Expression.Lambda(bodyExpression, expression.Parameters);
Expression<Func<IOrderedQueryable<T>>> sortMethod;
if (firstSort)
if (ascending) sortMethod = () => source.OrderBy<T, object>(k => null!);
else sortMethod = () => source.OrderByDescending<T, object>(k => null!);
else
if (ascending) sortMethod = () => ((IOrderedQueryable<T>)source).ThenBy<T, object>(k => null!);
else sortMethod = () => ((IOrderedQueryable<T>)source).ThenByDescending<T, object>(k => null!);
Expression<Func<IOrderedQueryable<T>>> sortMethod = firstSort
? ascending
? () => source.OrderBy<T, object>(k => null!)
: () => source.OrderByDescending<T, object>(k => null!)
: ascending
? () => ((IOrderedQueryable<T>)source).ThenBy<T, object>(k => null!)
: () => ((IOrderedQueryable<T>)source).ThenByDescending<T, object>(k => null!);

var methodCallExpression = (MethodCallExpression)sortMethod.Body;
var method = methodCallExpression.Method.GetGenericMethodDefinition();
var genericSortMethod = method.MakeGenericMethod(typeof(T), bodyExpression.Type);
var orderedQuery = (IOrderedQueryable<T>)genericSortMethod.Invoke(source, new object[] { source, sortLambda })!;
return orderedQuery;
return (IOrderedQueryable<T>)genericSortMethod.Invoke(source, new object[] { source, sortLambda })!;
}

private static IOrderedEnumerable<T> GetOrderedQuery<T>(this IEnumerable<T> source, Expression<Func<T, object>> expression, bool ascending, bool firstSort)
{
var bodyExpression = (MemberExpression)(expression.Body.NodeType == ExpressionType.Convert ? ((UnaryExpression)expression.Body).Operand : expression.Body);
var sortLambda = Expression.Lambda(bodyExpression, expression.Parameters);
Expression<Func<IOrderedEnumerable<T>>> sortMethod;
if (firstSort)
if (ascending) sortMethod = () => source.OrderBy<T, object>(k => null!);
else sortMethod = () => source.OrderByDescending<T, object>(k => null!);
else
if (ascending) sortMethod = () => ((IOrderedEnumerable<T>)source).ThenBy<T, object>(k => null!);
else sortMethod = () => ((IOrderedEnumerable<T>)source).ThenByDescending<T, object>(k => null!);

Expression<Func<IOrderedEnumerable<T>>> sortMethod = firstSort
? ascending
? () => source.OrderBy<T, object>(k => null!)
: () => source.OrderByDescending<T, object>(k => null!)
: ascending
? () => ((IOrderedEnumerable<T>)source).ThenBy<T, object>(k => null!)
: () => ((IOrderedEnumerable<T>)source).ThenByDescending<T, object>(k => null!);
if (sortMethod.Body is not MethodCallExpression methodCallExpression)
throw new Exception("oops");

var meth = methodCallExpression.Method.GetGenericMethodDefinition();
var genericSortMethod = meth.MakeGenericMethod(typeof(T), bodyExpression.Type);
var orderedQuery = (IOrderedEnumerable<T>)genericSortMethod.Invoke(source, new object[] { source, sortLambda.Compile() })!;
return orderedQuery;
return (IOrderedEnumerable<T>)genericSortMethod.Invoke(source, new object[] { source, sortLambda.Compile() })!;
}

private static Dictionary<string, bool> ProcessSortParam<T>(IEnumerable<string?> sortFields,
Expand Down
2 changes: 1 addition & 1 deletion src/Monaco.Template.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>Monaco.Template</id>
<version>2.0.4</version>
<version>2.1.0</version>
<title>Monaco Template</title>
<description>
Templates for .NET projects
Expand Down

0 comments on commit 3596c65

Please sign in to comment.