Skip to content
17 changes: 8 additions & 9 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<Project>

<PropertyGroup>
<NetCoreAppVersion>netcoreapp2.2</NetCoreAppVersion>
<NetStandardVersion>netstandard2.0</NetStandardVersion>
<AspNetCoreVersion>2.2.*</AspNetCoreVersion>
<MicrosoftLoggingVersion>2.2.*</MicrosoftLoggingVersion>
<MicrosoftConfigurationVersion>2.2.*</MicrosoftConfigurationVersion>
<MicrosoftOptionsVersion>2.2.*</MicrosoftOptionsVersion>
<EFCoreVersion>2.2.*</EFCoreVersion>
<EFCoreToolsVersion>2.2.*</EFCoreToolsVersion>
<NetCoreAppVersion>netcoreapp3.0</NetCoreAppVersion>
<NetStandardVersion>netstandard2.1</NetStandardVersion>
<AspNetCoreVersion>3.*</AspNetCoreVersion>
<MicrosoftLoggingVersion>3.*</MicrosoftLoggingVersion>
<MicrosoftConfigurationVersion>3.*</MicrosoftConfigurationVersion>
<MicrosoftOptionsVersion>3.*</MicrosoftOptionsVersion>
<EFCoreVersion>3.*</EFCoreVersion>
<EFCoreToolsVersion>3.*</EFCoreToolsVersion>
<NpgsqlVersion>4.0.0</NpgsqlVersion>
<NpgsqlPostgreSQLVersion>2.1.0</NpgsqlPostgreSQLVersion>
<TuplesVersion>4.5.0</TuplesVersion>
Expand Down
15 changes: 15 additions & 0 deletions JsonApiDotnetCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonApiDotNetCore", "src\Js
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GettingStarted", "src\Examples\GettingStarted\GettingStarted.csproj", "{067FFD7A-C66B-473D-8471-37F5C95DF61C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationTests", "test\IntegrationTests\IntegrationTests.csproj", "{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -158,6 +160,18 @@ Global
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|x64.Build.0 = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|x86.ActiveCfg = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|x86.Build.0 = Release|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Debug|x64.ActiveCfg = Debug|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Debug|x64.Build.0 = Debug|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Debug|x86.ActiveCfg = Debug|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Debug|x86.Build.0 = Debug|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Release|Any CPU.Build.0 = Release|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Release|x64.ActiveCfg = Release|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Release|x64.Build.0 = Release|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Release|x86.ActiveCfg = Release|Any CPU
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -173,6 +187,7 @@ Global
{789085E1-048F-4996-B600-791B9CA3A663} = {026FBC6C-AF76-4568-9B87-EC73457899FD}
{8BCFF95F-4850-427C-AEDB-B5B4F62B2C7B} = {026FBC6C-AF76-4568-9B87-EC73457899FD}
{21D27239-138D-4604-8E49-DCBE41BCE4C8} = {7A2B7ADD-ECB5-4D00-AA6A-D45BD11C97CF}
{CEB08B86-6BF1-4227-B20F-45AE9C1CC6D9} = {24B15015-62E5-42E1-9BA0-ECE6BE7AA15F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A2421882-8F0A-4905-928F-B550B192F9A4}
Expand Down
3 changes: 1 addition & 2 deletions src/Examples/GettingStarted/GettingStarted.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>$(NetCoreAppVersion)</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand All @@ -14,7 +14,6 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="$(EFCoreVersion)" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="$(EFCoreVersion)" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="$(EFCoreVersion)" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="$(EFCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="$(MicrosoftConfigurationVersion)" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftLoggingVersion)" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="$(NpgsqlPostgreSQLVersion)" />
<PackageReference Include="Npgsql" Version="$(NpgsqlVersion)" />
Expand Down
2 changes: 0 additions & 2 deletions src/Examples/ReportsExample/ReportsExample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftLoggingVersion)" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="$(NpgsqlPostgreSQLVersion)" />
<PackageReference Include="Npgsql" Version="$(NpgsqlVersion)" />
Expand Down
28 changes: 20 additions & 8 deletions src/JsonApiDotNetCore/Data/DefaultResourceRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,13 @@ public virtual async Task<IEnumerable<TResource>> PageAsync(IQueryable<TResource
}

// since EntityFramework does not support IQueryable.Reverse(), we need to know the number of queried entities
int numberOfEntities = await this.CountAsync(entities);


entities = entities.Reverse();


// may be negative
int virtualFirstIndex = numberOfEntities - pageSize * Math.Abs(pageNumber);
int virtualFirstIndex = pageSize * Math.Abs(pageNumber);
int numberOfElementsInPage = Math.Min(pageSize, virtualFirstIndex + pageSize);

return await ToListAsync(entities
Expand All @@ -321,9 +324,14 @@ public virtual async Task<IEnumerable<TResource>> PageAsync(IQueryable<TResource
/// <inheritdoc />
public async Task<int> CountAsync(IQueryable<TResource> entities)
{
return (entities is IAsyncEnumerable<TResource>)
? await entities.CountAsync()
: entities.Count();
if (entities is IAsyncEnumerable<TResource>)
{
return await entities.CountAsync();
}
else
{
return entities.Count();
}
}

/// <inheritdoc />
Expand All @@ -337,9 +345,13 @@ public async Task<TResource> FirstOrDefaultAsync(IQueryable<TResource> entities)
/// <inheritdoc />
public async Task<IReadOnlyList<TResource>> ToListAsync(IQueryable<TResource> entities)
{
return (entities is IAsyncEnumerable<TResource>)
? await entities.ToListAsync()
: entities.ToList();
if(entities is IAsyncEnumerable<TResource>)
{
return await entities.ToListAsync();
} else
{
return entities.ToList();
}
}

/// <summary>
Expand Down
16 changes: 16 additions & 0 deletions src/JsonApiDotNetCore/Extensions/DbContextExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using JsonApiDotNetCore.Models;
using Microsoft.EntityFrameworkCore;
Expand Down Expand Up @@ -108,5 +109,20 @@ private void Proxy(Action<IDbContextTransaction> func)
if(_shouldExecute)
func(_transaction);
}

public Task CommitAsync(CancellationToken cancellationToken = default)
{
return _transaction.CommitAsync(cancellationToken);
}

public Task RollbackAsync(CancellationToken cancellationToken = default)
{
return _transaction.RollbackAsync(cancellationToken);
}

public ValueTask DisposeAsync()
{
return _transaction.DisposeAsync();
}
}
}
2 changes: 1 addition & 1 deletion src/JsonApiDotNetCore/Extensions/ModelStateExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System;
using System.Linq;
using System.Reflection;
using JsonApiDotNetCore.Internal;
using JsonApiDotNetCore.Models;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.EntityFrameworkCore.Internal;

namespace JsonApiDotNetCore.Extensions
{
Expand Down
1 change: 0 additions & 1 deletion src/JsonApiDotNetCore/Formatters/JsonApiOutputFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public bool CanWriteResult(OutputFormatterCanWriteContext context)

return string.IsNullOrEmpty(contentTypeString) || contentTypeString == Constants.ContentType;
}

public async Task WriteAsync(OutputFormatterWriteContext context)
{
var writer = context.HttpContext.RequestServices.GetService<IJsonApiWriter>();
Expand Down
4 changes: 1 addition & 3 deletions src/JsonApiDotNetCore/JsonApiDotNetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@
<ItemGroup>
<PackageReference Include="Ben.Demystifier" Version="0.1.1" />
<PackageReference Include="Humanizer" Version="2.4.2" />
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="$(EFCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftLoggingVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<!-- <PackageReference Include="System.Memory" Version="4.5.0" /> -->
<PackageReference Include="System.ValueTuple" Version="$(TuplesVersion)" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta-62925-02" PrivateAssets="All" />
</ItemGroup>
Expand Down
27 changes: 27 additions & 0 deletions src/JsonApiDotNetCore/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:63521/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"JsonApiDotNetCore": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:63522/"
}
}
}
60 changes: 60 additions & 0 deletions test/IntegrationTests/Data/EntityRepositoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using JsonApiDotNetCore.Builders;
using JsonApiDotNetCore.Data;
using JsonApiDotNetCoreExample.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace JADNC.IntegrationTests.Data
{
public class EntityRepositoryTests
{


public EntityRepositoryTests()
{
// setup database + services
// seed
}
[Theory]
[InlineData(6, -1, new[] { 4, 5, 6, 7, 8, 9 })]
[InlineData(6, -2, new[] { 1, 2, 3 })]
[InlineData(20, -1, new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 })]
public async Task Paging_PageNumberIsNegative_PageCorrectIds(int pageSize, int pageNumber, int[] expectedIds)
{
// Arrange
var todoItems = DbSetMock.Create(TodoItems(1, 2, 3, 4, 5, 6, 7, 8, 9)).Object;
var repository = GetRepository();

// Act
var result = await repository.PageAsync(todoItems, pageSize, pageNumber);

// Assert
Assert.Equal(TodoItems(expectedIds), result, new IdComparer<TodoItem>());
}


private DefaultResourceRepository<TodoItem> GetRepository()
{

var contextResolverMock = new Mock<IDbContextResolver>();
_contextMock
.Setup(m => m.Set<TodoItem>())
.Returns(_dbSetMock.Object);

contextResolverMock
.Setup(m => m.GetContext())
.Returns(_contextMock.Object);

var resourceGraph = new ResourceGraphBuilder().AddResource<TodoItem>().Build();


return new DefaultResourceRepository<TodoItem>(
_targetedFieldsMock.Object,
_contextResolverMock.Object,
resourceGraph, null, null);
}
}
}
26 changes: 26 additions & 0 deletions test/IntegrationTests/IntegrationTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>

<IsPackable>false</IsPackable>

<RootNamespace>JADNC.IntegrationTests</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.0.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\JsonApiDotNetCore\JsonApiDotNetCore.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Models\" />
</ItemGroup>

</Project>
14 changes: 14 additions & 0 deletions test/IntegrationTests/UnitTest1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using Xunit;

namespace IntegrationTests
{
public class UnitTest1
{
[Fact]
public void Test1()
{

}
}
}
Loading