Skip to content

Commit 065ff76

Browse files
Fix protected-name pagination counts and deterministic fake ordering
Co-authored-by: frasermolyneux <34033625+frasermolyneux@users.noreply.github.com>
1 parent 5b94ca2 commit 065ff76

4 files changed

Lines changed: 37 additions & 13 deletions

File tree

src/XtremeIdiots.Portal.Repository.Api.Client.Testing.Tests/FakePlayersApiTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,22 @@ public async Task GetProtectedNames_FiltersByGameType()
145145
Assert.Equal(cod4Player.PlayerId, items[0].PlayerId);
146146
}
147147

148+
[Fact]
149+
public async Task GetProtectedNames_OrdersByNameBeforePagination()
150+
{
151+
var fake = new FakePlayersApi();
152+
var player = RepositoryDtoFactory.CreatePlayer(gameType: GameType.CallOfDuty4);
153+
fake.AddPlayer(player);
154+
fake.AddProtectedName(RepositoryDtoFactory.CreateProtectedName(playerId: player.PlayerId, name: "Zulu"));
155+
fake.AddProtectedName(RepositoryDtoFactory.CreateProtectedName(playerId: player.PlayerId, name: "Alpha"));
156+
157+
var result = await fake.GetProtectedNames(0, 1);
158+
159+
Assert.Equal(HttpStatusCode.OK, result.StatusCode);
160+
var item = Assert.Single(result.Result!.Data!.Items!);
161+
Assert.Equal("Alpha", item.Name);
162+
}
163+
148164
[Fact]
149165
public void AddPlayer_FluentChaining_Works()
150166
{

src/XtremeIdiots.Portal.Repository.Api.Client.Testing/Fakes/FakePlayersApi.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,11 @@ public Task<ApiResult<CollectionModel<ProtectedNameDto>>> GetProtectedNames(int
138138
if (gameType.HasValue)
139139
items = items.Where(pn => _players.TryGetValue(pn.PlayerId, out var player) && player.GameType == gameType.Value);
140140

141-
var paginatedItems = items.Skip(skipEntries).Take(takeEntries).ToList();
141+
var paginatedItems = items
142+
.OrderBy(pn => pn.Name)
143+
.Skip(skipEntries)
144+
.Take(takeEntries)
145+
.ToList();
142146
var collection = new CollectionModel<ProtectedNameDto> { Items = paginatedItems };
143147
return Task.FromResult(new ApiResult<CollectionModel<ProtectedNameDto>>(HttpStatusCode.OK, new ApiResponse<CollectionModel<ProtectedNameDto>>(collection)));
144148
}

src/XtremeIdiots.Portal.Repository.Api.Tests.V1/Controllers/V1/PlayersControllerTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,9 @@ public async Task GetProtectedNames_WithGameTypeFilter_ReturnsOnlyMatchingGameTy
953953
Assert.Equal(HttpStatusCode.OK, result.StatusCode);
954954
var item = Assert.Single(result.Result!.Data!.Items!);
955955
Assert.Equal(cod4PlayerId, item.PlayerId);
956+
Assert.NotNull(result.Result.Pagination);
957+
Assert.Equal(2, result.Result.Pagination!.TotalCount);
958+
Assert.Equal(1, result.Result.Pagination.FilteredCount);
956959
}
957960

958961
#endregion

src/XtremeIdiots.Portal.Repository.Api.V1/Controllers/V1/PlayersController.cs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,12 +1064,15 @@ public async Task<IActionResult> GetProtectedNames(
10641064
/// <returns>An API result containing a paginated collection of protected names.</returns>
10651065
async Task<ApiResult<CollectionModel<ProtectedNameDto>>> IPlayersApi.GetProtectedNames(int skipEntries, int takeEntries, GameType? gameType)
10661066
{
1067-
IQueryable<ProtectedName> query = context.ProtectedNames.AsNoTracking();
1067+
IQueryable<ProtectedName> totalCountQuery = context.ProtectedNames.AsNoTracking();
1068+
var totalCount = await totalCountQuery.CountAsync().ConfigureAwait(false);
1069+
1070+
IQueryable<ProtectedName> filteredQuery = totalCountQuery;
10681071

10691072
if (gameType.HasValue)
10701073
{
10711074
var gameTypeValue = (int)gameType.Value;
1072-
query = query
1075+
filteredQuery = filteredQuery
10731076
.Where(pn => pn.PlayerId.HasValue)
10741077
.Join(
10751078
context.Players.AsNoTracking().Where(p => p.GameType == gameTypeValue),
@@ -1078,13 +1081,11 @@ async Task<ApiResult<CollectionModel<ProtectedNameDto>>> IPlayersApi.GetProtecte
10781081
(pn, _) => pn);
10791082
}
10801083

1081-
query = query
1082-
.Include(pn => pn.Player)
1083-
.Include(pn => pn.CreatedByUserProfile);
1084-
1085-
var totalCount = await query.CountAsync().ConfigureAwait(false);
1084+
var filteredCount = await filteredQuery.CountAsync().ConfigureAwait(false);
10861085

1087-
var paginatedQuery = query
1086+
var paginatedQuery = filteredQuery
1087+
.Include(pn => pn.Player)
1088+
.Include(pn => pn.CreatedByUserProfile)
10881089
.OrderBy(pn => pn.Name)
10891090
.Skip(skipEntries)
10901091
.Take(takeEntries);
@@ -1097,7 +1098,7 @@ async Task<ApiResult<CollectionModel<ProtectedNameDto>>> IPlayersApi.GetProtecte
10971098

10981099
return new ApiResponse<CollectionModel<ProtectedNameDto>>(data)
10991100
{
1100-
Pagination = new ApiPagination(totalCount, totalCount, skipEntries, takeEntries)
1101+
Pagination = new ApiPagination(totalCount, filteredCount, skipEntries, takeEntries)
11011102
}.ToApiResult();
11021103
}
11031104

@@ -1232,11 +1233,11 @@ async Task<ApiResult> IPlayersApi.CreateProtectedName(CreateProtectedNameDto cre
12321233
&& pn.Name.ToLower() == createProtectedNameDto.Name.ToLower()
12331234
&& pn.PlayerId.HasValue)
12341235
.Join(
1235-
context.Players.AsNoTracking(),
1236+
context.Players.AsNoTracking().Where(p => p.GameType == playerGameType.Value),
12361237
pn => pn.PlayerId!.Value,
12371238
p => p.PlayerId,
1238-
(_, p) => p.GameType)
1239-
.AnyAsync(gt => gt == playerGameType.Value)
1239+
(pn, _) => pn)
1240+
.AnyAsync()
12401241
.ConfigureAwait(false);
12411242

12421243
if (nameExistsInGameType)

0 commit comments

Comments
 (0)