Skip to content

Commit

Permalink
Added PagedResult extensions. (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
fiseni authored Sep 27, 2024
1 parent 0af6626 commit c43347b
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,30 @@ public static IQueryable<TResult> WithSpecification<TSource, TResult>(
evaluator ??= SpecificationEvaluator.Default;
return evaluator.GetQuery(source, specification);
}

public static Task<PagedResult<TSource>> ToPagedResultAsync<TSource>(
this IQueryable<TSource> source,
PagingFilter filter,
CancellationToken cancellationToken = default)
where TSource : class
=> ToPagedResultAsync(source, filter, PaginationSettings.Default, cancellationToken);

public static async Task<PagedResult<TSource>> ToPagedResultAsync<TSource>(
this IQueryable<TSource> source,
PagingFilter filter,
PaginationSettings paginationSettings,
CancellationToken cancellationToken = default)
where TSource : class
{
var count = await source.CountAsync(cancellationToken);
var pagination = new Pagination(paginationSettings, count, filter);

var query = source
.Skip(pagination.Skip)
.Take(pagination.Take);

var data = await query.ToListAsync(cancellationToken);

return new PagedResult<TSource>(data, pagination);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
namespace Tests.Extensions;

[Collection("SharedCollection")]
public class LikeExtensionTests(TestFactory factory) : IntegrationTest(factory)
public class Extensions_Like(TestFactory factory) : IntegrationTest(factory)
{
[Fact]
public void Like_GivenSpecWithMultipleLike()
public void QueriesMatch_GivenSpecWithMultipleLike()
{
var storeTerm = "ab";
var companyTerm = "ab";
Expand All @@ -28,7 +28,7 @@ public void Like_GivenSpecWithMultipleLike()
}

[Fact]
public void Like_GivenEmptySpec()
public void QueriesMatch_GivenEmptySpec()
{
var spec = new Specification<Store>();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
namespace Tests.Extensions;

[Collection("SharedCollection")]
public class Extensions_ToPagedResult(TestFactory factory) : IntegrationTest(factory)
{
[Fact]
public async Task ReturnsPaginatedItems_GivenPagingFilter()
{
var expected = new List<Country>
{
new() { No = 4, Name = "b" },
};
await SeedRangeAsync<Country>(
[
new() { No = 9, Name = "a" },
new() { No = 9, Name = "c" },
new() { No = 1, Name = "b" },
new() { No = 2, Name = "b" },
new() { No = 3, Name = "b" },
new() { No = 4, Name = "b" },
new() { No = 9, Name = "d" },
]);

var filter = new PagingFilter() { Page = 2, PageSize = 3 };

var result = await DbContext.Countries
.Where(x => x.Name == "b")
.OrderBy(x => x.No)
.ToPagedResultAsync(filter);

result.Should().BeOfType<PagedResult<Country>>();
result.Pagination.Page.Should().Be(filter.Page);
result.Pagination.PageSize.Should().Be(filter.PageSize);
result.Data.Should().HaveCount(1);
result.Data.First().No.Should().Be(4);
}

[Fact]
public async Task ReturnsPaginatedItems_GivenPagingFilterAndPaginationSettings()
{
var expected = new List<Country>
{
new() { No = 3, Name = "b" },
new() { No = 4, Name = "b" },
};
await SeedRangeAsync<Country>(
[
new() { No = 9, Name = "a" },
new() { No = 9, Name = "c" },
new() { No = 1, Name = "b" },
new() { No = 2, Name = "b" },
new() { No = 3, Name = "b" },
new() { No = 4, Name = "b" },
new() { No = 9, Name = "d" },
]);

var paginationSettings = new PaginationSettings(2, 2);
var filter = new PagingFilter() { Page = 2, PageSize = 3 };

var result = await DbContext.Countries
.Where(x => x.Name == "b")
.OrderBy(x => x.No)
.ToPagedResultAsync(filter, paginationSettings);

result.Should().BeOfType<PagedResult<Country>>();
result.Pagination.Page.Should().Be(filter.Page);
result.Pagination.PageSize.Should().Be(paginationSettings.DefaultPageSize);
result.Data.Should().HaveCount(2);
result.Data.First().No.Should().Be(3);
}

[Fact]
public async Task ReturnsPaginatedItemsWithAggregatedTakeSkip_GivenPagingFilterAndTakeSkip()
{
var expected = new List<Country>
{
new() { No = 2, Name = "b" },
new() { No = 3, Name = "b" },
};
await SeedRangeAsync<Country>(
[
new() { No = 9, Name = "a" },
new() { No = 9, Name = "c" },
new() { No = 1, Name = "b" },
new() { No = 2, Name = "b" },
new() { No = 3, Name = "b" },
new() { No = 4, Name = "b" },
new() { No = 9, Name = "d" },
]);

var filter = new PagingFilter() { Page = 2, PageSize = 3 };

var result = await DbContext.Countries
.Where(x => x.Name == "b")
.OrderBy(x => x.No)
.Skip(1)
.Take(2)
.ToPagedResultAsync(filter);

result.Should().BeOfType<PagedResult<Country>>();
result.Pagination.Page.Should().Be(PaginationSettings.Default.DefaultPage);
result.Pagination.PageSize.Should().Be(filter.PageSize);
result.Data.Should().HaveCount(2);
result.Data.First().No.Should().Be(2);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
namespace Tests.Extensions;

[Collection("SharedCollection")]
public class DbSetExtensionsTests(TestFactory factory) : IntegrationTest(factory)
public class Extensions_WithSpecification(TestFactory factory) : IntegrationTest(factory)
{
public record CountryDto(string? Name);
public record ProductImageDto(string? ImageUrl);

[Fact]
public void WithSpecification_GivenFullQuery()
public void QueriesMatch_GivenFullQuery()
{
var id = 1;
var name = "Store1";
Expand Down Expand Up @@ -60,7 +59,7 @@ public void WithSpecification_GivenFullQuery()
}

[Fact]
public void WithSpecification_GivenFullQueryWithSelect()
public void QueriesMatch_GivenFullQueryWithSelect()
{
var id = 1;
var name = "Store1";
Expand Down Expand Up @@ -115,7 +114,7 @@ public void WithSpecification_GivenFullQueryWithSelect()
}

[Fact]
public void WithSpecification_GivenFullQueryWithSelectMany()
public void QueriesMatch_GivenFullQueryWithSelectMany()
{
var id = 1;
var name = "Store1";
Expand Down Expand Up @@ -170,7 +169,7 @@ public void WithSpecification_GivenFullQueryWithSelectMany()
}

[Fact]
public void WithSpecification_GivenCustomEvaluator()
public void QueriesMatch_GivenCustomEvaluator()
{
var id = 1;

Expand All @@ -192,7 +191,7 @@ public void WithSpecification_GivenCustomEvaluator()
}

[Fact]
public void WithSpecification_GivenSelectorAndCustomEvaluator()
public void QueriesMatch_GivenSelectorAndCustomEvaluator()
{
var id = 1;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ await SeedRangeAsync(
var result = await repo.AnyAsync(spec);

result.Should().BeTrue();

// Ensure that the spec's pagination is not altered.
spec.Skip.Should().Be(3);
spec.Take.Should().Be(1);
}

[Fact]
Expand Down Expand Up @@ -169,5 +173,9 @@ await SeedRangeAsync<Country>(
var result = await repo.AnyAsync(spec);

result.Should().BeTrue();

// Ensure that the spec's pagination is not altered.
spec.Skip.Should().Be(3);
spec.Take.Should().Be(1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ await SeedRangeAsync(
var result = await repo.CountAsync(spec);

result.Should().Be(expected.Count);

// Ensure that the spec's pagination is not altered.
spec.Skip.Should().Be(1);
spec.Take.Should().Be(1);
}

[Fact]
Expand Down Expand Up @@ -169,5 +173,9 @@ await SeedRangeAsync<Country>(
var result = await repo.CountAsync(spec);

result.Should().Be(expected.Count);

// Ensure that the spec's pagination is not altered.
spec.Skip.Should().Be(1);
spec.Take.Should().Be(1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,6 @@ public async Task ProjectToListAsync_ReturnsPaginatedItems_GivenSpecAndPagingFil
{
var expected = new List<CountryDto>
{
new(1, "b"),
new(2, "b"),
new(3, "b"),
new(4, "b"),
};
await SeedRangeAsync<Country>(
Expand Down Expand Up @@ -187,9 +184,6 @@ public async Task ProjectToListAsync_IgnoresSpecPagination_GivenSpecAndPagingFil
{
var expected = new List<CountryDto>
{
new(1, "b"),
new(2, "b"),
new(3, "b"),
new(4, "b"),
};
await SeedRangeAsync<Country>(
Expand Down

0 comments on commit c43347b

Please sign in to comment.