Skip to content

Commit 32b3c64

Browse files
committed
chore: reorganising test models in unit test project
1 parent a33fdac commit 32b3c64

31 files changed

+660
-576
lines changed

src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ private bool IsHasOneRelationship(string internalRelationshipName, Type type)
201201
/// <inheritdoc />
202202
public void DetachRelationshipPointers(TEntity entity)
203203
{
204-
205204
foreach (var relationshipAttr in _targetedFields.Relationships)
206205
{
207206
if (relationshipAttr is HasOneAttribute hasOneAttr)

src/JsonApiDotNetCore/Extensions/IServiceCollectionExtensions.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ public static void AddJsonApiInternals(
191191
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
192192
services.AddSingleton<IContextEntityProvider>(graph);
193193
services.AddScoped<ICurrentRequest, CurrentRequest>();
194-
services.AddScoped<IPageQueryService, PageService>();
195194
services.AddScoped<IScopedServiceProvider, RequestScopedServiceProvider>();
196195
services.AddScoped<JsonApiRouteHandler>();
197196
services.AddScoped<IJsonApiWriter, JsonApiWriter>();
@@ -200,21 +199,28 @@ public static void AddJsonApiInternals(
200199
services.AddScoped(typeof(GenericProcessor<>));
201200
services.AddScoped<IQueryAccessor, QueryAccessor>();
202201
services.AddScoped<IQueryParser, QueryParser>();
203-
services.AddScoped<IIncludeService, IncludeService>();
204-
services.AddScoped<ISparseFieldsService, SparseFieldsService>();
202+
205203
services.AddScoped<ITargetedFields, TargetedFields>();
206204
services.AddScoped<IFieldsExplorer, FieldsExplorer>();
207-
services.AddScoped<IAttributeBehaviourService, OmitNullService>();
208205
services.AddScoped<IFieldsToSerialize, FieldsToSerialize>();
209206

210207
AddServerSerialization(services);
211-
208+
AddQueryParameterServices(services);
212209
if (jsonApiOptions.EnableResourceHooks)
213210
AddResourceHooks(services);
214211

215212
services.AddScoped<IInverseRelationships, InverseRelationships>();
216213
}
217214

215+
private static void AddQueryParameterServices(IServiceCollection services)
216+
{
217+
services.AddScoped<IIncludeService, IncludeService>();
218+
services.AddScoped<ISparseFieldsService, SparseFieldsService>();
219+
services.AddScoped<IPageQueryService, PageService>();
220+
221+
}
222+
223+
218224
private static void AddResourceHooks(IServiceCollection services)
219225
{
220226
services.AddSingleton(typeof(IHooksDiscovery<>), typeof(HooksDiscovery<>));

src/JsonApiDotNetCore/Middleware/JsonApiActionFilter.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,10 @@ protected void HandleUriParameters()
5757
{
5858
if (_httpContext.Request.Query.Count > 0)
5959
{
60-
var querySet = _queryParser.Parse(_httpContext.Request.Query);
61-
_currentRequest.QuerySet = querySet; //this shouldn't be exposed?
62-
_pageManager.PageSize = querySet.PageQuery.PageSize ?? _pageManager.PageSize;
63-
_pageManager.CurrentPage = querySet.PageQuery.PageOffset ?? _pageManager.CurrentPage;
64-
60+
_queryParser.Parse(_httpContext.Request.Query);
61+
//_currentRequest.QuerySet = querySet; //this shouldn't be exposed?
62+
//_pageManager.PageSize = querySet.PageQuery.PageSize ?? _pageManager.PageSize;
63+
//_pageManager.CurrentPage = querySet.PageQuery.PageOffset ?? _pageManager.CurrentPage;
6564
}
6665
}
6766

src/JsonApiDotNetCore/QueryParameters/Common/IQueryParameterService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ internal interface IQueryParameterService
99
/// Parses the value of the query parameter. Invoked in the middleware.
1010
/// </summary>
1111
/// <param name="value">the value of the query parameter as parsed from the url</param>
12-
void Parse(string value);
12+
void Parse(string key, string value);
1313
/// <summary>
1414
/// The name of the query parameter as matched in the URL.
1515
/// </summary>

src/JsonApiDotNetCore/QueryParameters/Contracts/IAttributeBehaviourService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace JsonApiDotNetCore.Query
66
/// Encapsulates client overrides of omit null and omit default values behaviour
77
/// in <see cref="ResourceObjectBuilderSettings"/>
88
/// </summary>
9-
public interface IAttributeBehaviourService: IQueryParameterService
9+
public interface IAttributeBehaviourService
1010
{
1111
/// <summary>
1212
/// Value of client query param overriding the omit null values behaviour in the server serializer

src/JsonApiDotNetCore/QueryParameters/FilterService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace JsonApiDotNetCore.Query
44
{
55
public class FilterService : QueryParameterService
66
{
7-
public override void Parse(string value)
7+
public override void Parse(string key, string value)
88
{
99
throw new NotImplementedException();
1010
}

src/JsonApiDotNetCore/QueryParameters/IncludeService.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ namespace JsonApiDotNetCore.Query
1111

1212
public class IncludeService : QueryParameterService, IIncludeService
1313
{
14-
/// todo: make readonly
14+
/// todo: use read-only lists.
1515
private readonly List<List<RelationshipAttribute>> _includedChains;
1616
private readonly ICurrentRequest _currentRequest;
1717
private readonly IContextEntityProvider _provider;
18-
18+
private ContextEntity _primaryResourceContext;
1919
public IncludeService(ICurrentRequest currentRequest, IContextEntityProvider provider)
2020
{
2121
_currentRequest = currentRequest;
@@ -26,7 +26,10 @@ public IncludeService(ICurrentRequest currentRequest, IContextEntityProvider pro
2626
/// <summary>
2727
/// This constructor is used internally for testing.
2828
/// </summary>
29-
internal IncludeService() : this(null, null) { }
29+
internal IncludeService(ContextEntity primaryResourceContext, IContextEntityProvider provider) : this(currentRequest: null, provider: provider)
30+
{
31+
_primaryResourceContext = primaryResourceContext;
32+
}
3033

3134
/// <inheritdoc/>
3235
public List<List<RelationshipAttribute>> Get()
@@ -47,32 +50,34 @@ public override void Parse(string _, string value)
4750

4851
private void ParseChain(string chain)
4952
{
53+
_primaryResourceContext = _primaryResourceContext ?? _currentRequest.GetRequestResource();
54+
5055
var parsedChain = new List<RelationshipAttribute>();
51-
var resourceContext = _currentRequest.GetRequestResource();
5256
var chainParts = chain.Split(QueryConstants.DOT);
57+
var resourceContext = _primaryResourceContext;
5358
foreach (var relationshipName in chainParts)
5459
{
5560
var relationship = resourceContext.Relationships.SingleOrDefault(r => r.PublicRelationshipName == relationshipName);
5661
if (relationship == null)
57-
ThrowInvalidRelationshipError(resourceContext, relationshipName);
62+
throw InvalidRelationshipError(resourceContext, relationshipName);
5863

5964
if (relationship.CanInclude == false)
60-
ThrowCannotIncludeError(resourceContext, relationshipName);
65+
throw CannotIncludeError(resourceContext, relationshipName);
6166

6267
parsedChain.Add(relationship);
6368
resourceContext = _provider.GetContextEntity(relationship.DependentType);
6469
}
6570
_includedChains.Add(parsedChain);
6671
}
6772

68-
private void ThrowCannotIncludeError(ContextEntity resourceContext, string requestedRelationship)
73+
private JsonApiException CannotIncludeError(ContextEntity resourceContext, string requestedRelationship)
6974
{
70-
throw new JsonApiException(400, $"Including the relationship {requestedRelationship} on {resourceContext.EntityName} is not allowed");
75+
return new JsonApiException(400, $"Including the relationship {requestedRelationship} on {resourceContext.EntityName} is not allowed");
7176
}
7277

73-
private void ThrowInvalidRelationshipError(ContextEntity resourceContext, string requestedRelationship)
78+
private JsonApiException InvalidRelationshipError(ContextEntity resourceContext, string requestedRelationship)
7479
{
75-
throw new JsonApiException(400, $"Invalid relationship {requestedRelationship} on {resourceContext.EntityName}",
80+
return new JsonApiException(400, $"Invalid relationship {requestedRelationship} on {resourceContext.EntityName}",
7681
$"{resourceContext.EntityName} does not have a relationship named {requestedRelationship}");
7782
}
7883
}

src/JsonApiDotNetCore/QueryParameters/OmitDefaultValuedAttributesService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace JsonApiDotNetCore.Query
44
{
55
public class OmitDefaultService : QueryParameterService
66
{
7-
public override void Parse(string value)
7+
public override void Parse(string key, string value)
88
{
99
throw new NotImplementedException();
1010
}

src/JsonApiDotNetCore/QueryParameters/OmitNullValuedAttributesService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace JsonApiDotNetCore.Query
44
{
55
public class OmitNullService : QueryParameterService
66
{
7-
public override void Parse(string value)
7+
public override void Parse(string key, string value)
88
{
99
throw new NotImplementedException();
1010
}

src/JsonApiDotNetCore/QueryParameters/PageService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ public PageService(IJsonApiOptions options)
2626
/// <inheritdoc/>
2727
public int TotalPages => (TotalRecords == null) ? -1 : (int)Math.Ceiling(decimal.Divide(TotalRecords.Value, PageSize));
2828

29-
public override void Parse(string value)
29+
public override void Parse(string key, string value)
3030
{
3131
throw new NotImplementedException();
3232
}
3333

34+
3435
/// <inheritdoc/>
3536
public bool ShouldPaginate()
3637
{

src/JsonApiDotNetCore/QueryParameters/SortService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
namespace JsonApiDotNetCore.Query
44
{
5-
public class SortService: QueryParameterService
5+
public class SortService : QueryParameterService
66
{
7-
public override void Parse(string value)
7+
public override void Parse(string key, string value)
88
{
99
throw new NotImplementedException();
1010
}

src/JsonApiDotNetCore/QueryParameters/SparseFieldsService.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ public override void Parse(string key, string value)
5252
var includedFields = new List<string> { nameof(Identifiable.Id) };
5353

5454
var relationship = primaryResource.Relationships.SingleOrDefault(a => a.Is(typeName));
55-
if (relationship == default && string.Equals(typeName, primaryResource.EntityName, StringComparison.OrdinalIgnoreCase) == false)
56-
return; // includedFields;
55+
if (relationship == null && string.Equals(typeName, primaryResource.EntityName, StringComparison.OrdinalIgnoreCase) == false)
56+
throw new JsonApiException(400, $"fields[{typeName}] is invalid");
5757

5858
var fields = value.Split(QueryConstants.COMMA);
5959
foreach (var field in fields)
@@ -68,9 +68,6 @@ public override void Parse(string key, string value)
6868
if (!_selectedRelationshipFields.TryGetValue(relationship, out var registeredFields))
6969
_selectedRelationshipFields.Add(relationship, registeredFields = new List<AttrAttribute>());
7070
registeredFields.Add(attr);
71-
// e.g. "Owner.Name"
72-
//includedFields.Add(relationship.InternalRelationshipName + "." + attr.InternalAttributeName);
73-
7471
}
7572
else
7673
{
@@ -79,9 +76,6 @@ public override void Parse(string key, string value)
7976
throw new JsonApiException(400, $"'{primaryResource.EntityName}' does not contain '{field}'.");
8077

8178
(_selectedFields = _selectedFields ?? new List<AttrAttribute>()).Add(attr);
82-
83-
// e.g. "Name"
84-
//includedFields.Add(attr.InternalAttributeName);
8579
}
8680
}
8781
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Collections.Generic;
2+
using JsonApiDotNetCore.Internal.Query;
3+
4+
namespace JsonApiDotNetCore.Managers.Contracts
5+
{
6+
public class QuerySet
7+
{
8+
public List<FilterQuery> Filters { get; internal set; }
9+
public List<string> Fields { get; internal set; }
10+
public List<SortQuery> SortParameters { get; internal set; }
11+
}
12+
}

src/JsonApiDotNetCore/RequestServices/CurrentRequest.cs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
using JsonApiDotNetCore.Controllers;
22
using JsonApiDotNetCore.Internal;
3-
using JsonApiDotNetCore.Internal.Query;
43
using JsonApiDotNetCore.Managers.Contracts;
54
using JsonApiDotNetCore.Models;
65
using JsonApiDotNetCore.Query;
7-
using JsonApiDotNetCore.Services;
86
using Microsoft.AspNetCore.Http;
97
using System.Collections.Generic;
108

@@ -16,7 +14,6 @@ class CurrentRequest : ICurrentRequest
1614
private ContextEntity _contextEntity;
1715
public string BasePath { get; set; }
1816
public List<string> IncludedRelationships { get; set; }
19-
public QuerySet QuerySet { get; set; }
2017
public PageService PageManager { get; set; }
2118
public IQueryCollection FullQuerySet { get; set; }
2219
public QueryParams DisabledQueryParams { get; set; }
@@ -26,16 +23,7 @@ class CurrentRequest : ICurrentRequest
2623
public Dictionary<RelationshipAttribute, object> RelationshipsToUpdate { get; set; }
2724

2825
public RelationshipAttribute RequestRelationship { get; set; }
29-
30-
public List<string> GetFields()
31-
{
32-
return QuerySet?.Fields;
33-
}
34-
35-
public List<string> GetRelationships()
36-
{
37-
return QuerySet?.IncludedRelationships;
38-
}
26+
public QuerySet QuerySet { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
3927

4028
/// <summary>
4129
/// The main resource of the request.

src/JsonApiDotNetCore/Services/QueryParser.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace JsonApiDotNetCore.Services
1717

1818
public interface IQueryParser
1919
{
20-
QuerySet Parse(IQueryCollection query);
20+
void Parse(IQueryCollection query);
2121
}
2222

2323
public class QueryParser : IQueryParser
@@ -52,8 +52,6 @@ public virtual void Parse(IQueryCollection query)
5252
_primaryResource = _currentRequest.GetRequestResource();
5353
var disabledQueries = _currentRequest.DisabledQueryParams;
5454

55-
56-
5755
foreach (var pair in query)
5856
{
5957
if (pair.Key.StartsWith(QueryConstants.FILTER, StringComparison.Ordinal))
@@ -94,7 +92,6 @@ public virtual void Parse(IQueryCollection query)
9492
if (_options.AllowCustomQueryParameters == false)
9593
throw new JsonApiException(400, $"{pair} is not a valid query.");
9694
}
97-
;
9895
}
9996

10097
private void GetQueryParameterServices()
@@ -205,8 +202,6 @@ protected virtual List<SortQuery> ParseSortParameters(string value)
205202
return sortParameters;
206203
}
207204

208-
209-
210205
protected virtual AttrAttribute GetAttribute(string propertyName)
211206
{
212207
try
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Linq;
3+
using JsonApiDotNetCore.Internal;
4+
using JsonApiDotNetCore.Query;
5+
using Xunit;
6+
7+
namespace UnitTests.QueryParameters
8+
{
9+
public class IncludedServiceTests : QueryParametersUnitTestCollection
10+
{
11+
12+
public IncludeService GetService(ContextEntity resourceContext = null)
13+
{
14+
return new IncludeService(resourceContext ?? _articleResourceContext , _graph);
15+
}
16+
17+
[Fact]
18+
public void Parse_ShortChain_CanParse()
19+
{
20+
// arrange
21+
const string chain = "author";
22+
23+
var service = GetService();
24+
25+
// act
26+
service.Parse(null, "author");
27+
28+
// assert
29+
var chains = service.Get();
30+
Assert.Equal(1, chains.Count);
31+
var relationship = chains.First().First();
32+
Assert.Equal(chain, relationship.PublicRelationshipName);
33+
}
34+
35+
}
36+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using JsonApiDotNetCore.Builders;
2+
using JsonApiDotNetCore.Internal;
3+
using JsonApiDotNetCore.Internal.Contracts;
4+
using UnitTests.TestModels;
5+
6+
namespace UnitTests.QueryParameters
7+
{
8+
public class QueryParametersUnitTestCollection
9+
{
10+
protected readonly ContextEntity _articleResourceContext;
11+
protected readonly IResourceGraph _graph;
12+
13+
public QueryParametersUnitTestCollection()
14+
{
15+
var builder = new ResourceGraphBuilder();
16+
builder.AddResource<Article>();
17+
builder.AddResource<Person>();
18+
builder.AddResource<Blog>();
19+
builder.AddResource<Food>();
20+
builder.AddResource<Song>();
21+
_graph = builder.Build();
22+
_articleResourceContext = _graph.GetContextEntity<Article>();
23+
}
24+
}
25+
}

test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/BeforeDelete_WithDbValue_Tests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Linq;
88
using Xunit;
99

10+
1011
namespace UnitTests.ResourceHooks
1112
{
1213
public class BeforeDelete_WithDbValues_Tests : HooksTestsSetup

0 commit comments

Comments
 (0)