Skip to content

Commit

Permalink
Resolve #415
Browse files Browse the repository at this point in the history
  • Loading branch information
sei-bstein committed Feb 18, 2025
1 parent 9280a14 commit 4f5473c
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public async Task GetExpiredChallengesForSync_WithPlayerWithNullishEndDate_DoesN
var store = BuildTestableStore(challenge);
var sut = new ChallengeSyncService
(
A.Fake<IActingUserService>(),
A.Fake<ConsoleActorMap>(),
A.Fake<IGameEngineService>(),
A.Fake<ILogger<IChallengeSyncService>>(),
Expand Down Expand Up @@ -59,6 +60,7 @@ public async Task GetExpiredChallengesForSync_WithPlayerSessionEndInFuture_DoesN
var store = BuildTestableStore(challenge);
var sut = new ChallengeSyncService
(
A.Fake<IActingUserService>(),
A.Fake<ConsoleActorMap>(),
A.Fake<IGameEngineService>(),
A.Fake<ILogger<IChallengeSyncService>>(),
Expand Down Expand Up @@ -91,6 +93,7 @@ public async Task GetExpiredChallengesForSync_WithChallengeAlreadySynced_DoesNot
var store = BuildTestableStore(challenge);
var sut = new ChallengeSyncService
(
A.Fake<IActingUserService>(),
A.Fake<ConsoleActorMap>(),
A.Fake<IGameEngineService>(),
A.Fake<ILogger<IChallengeSyncService>>(),
Expand Down Expand Up @@ -123,6 +126,7 @@ public async Task GetExpiredChallengesForSync_WithNonNullishEndDate_DoesNotSync(
var store = BuildTestableStore(challenge);
var sut = new ChallengeSyncService
(
A.Fake<IActingUserService>(),
A.Fake<ConsoleActorMap>(),
A.Fake<IGameEngineService>(),
A.Fake<ILogger<IChallengeSyncService>>(),
Expand Down Expand Up @@ -155,6 +159,7 @@ public async Task GetExpiredChallengesForSync_WithAllRequiredCriteriaAndNullishE
var store = BuildTestableStore(challenge);
var sut = new ChallengeSyncService
(
A.Fake<IActingUserService>(),
A.Fake<ConsoleActorMap>(),
A.Fake<IGameEngineService>(),
A.Fake<ILogger<IChallengeSyncService>>(),
Expand Down
4 changes: 4 additions & 0 deletions src/Gameboard.Api/Features/Challenge/ChallengeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ await Hub.Clients.Group(result.TeamId).ChallengeEvent
return result;
}

[HttpPut("/api/challenge/{challengeId}/sync")]
public Task<GameEngineGameState> Sync([FromRoute] string challengeId, CancellationToken cancellationToken)
=> _mediator.Send(new SyncChallengeCommand(challengeId), cancellationToken);

/// <summary>
/// Grade a challenge
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Threading;
using System.Threading.Tasks;
using Gameboard.Api.Features.GameEngine;
using Gameboard.Api.Features.Users;
using Gameboard.Api.Structure.MediatR;
using MediatR;

namespace Gameboard.Api.Features.Challenges;

public record SyncChallengeCommand(string ChallengeId) : IRequest<GameEngineGameState>;

internal sealed class SyncChallengeHandler
(
IChallengeSyncService challengeSyncService,
IValidatorService validator
) : IRequestHandler<SyncChallengeCommand, GameEngineGameState>
{
public async Task<GameEngineGameState> Handle(SyncChallengeCommand request, CancellationToken cancellationToken)
{
await validator
.Auth(c => c.Require(PermissionKey.Admin_View))
.AddEntityExistsValidator<Data.Challenge>(request.ChallengeId)
.Validate(cancellationToken);

return await challengeSyncService.Sync(request.ChallengeId, cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Gameboard.Api.Features.Challenges;

public interface IChallengeSyncService
{
Task<GameEngineGameState> Sync(string challengeId, CancellationToken cancellationToken);
Task Sync(Data.Challenge challenge, GameEngineGameState challengeState, string actingUserId, CancellationToken cancellationToken);
Task SyncExpired(CancellationToken cancellationToken);
}
Expand All @@ -25,6 +26,7 @@ public interface IChallengeSyncService
/// </summary>
internal class ChallengeSyncService
(
IActingUserService actingUser,
ConsoleActorMap consoleActorMap,
IGameEngineService gameEngine,
ILogger<IChallengeSyncService> logger,
Expand All @@ -33,13 +35,31 @@ internal class ChallengeSyncService
IStore store
) : IChallengeSyncService
{
private readonly IActingUserService _actingUser = actingUser;
private readonly ConsoleActorMap _consoleActorMap = consoleActorMap;
private readonly IGameEngineService _gameEngine = gameEngine;
private readonly ILogger<IChallengeSyncService> _logger = logger;
private readonly IMapper _mapper = mapper;
private readonly INowService _now = now;
private readonly IStore _store = store;

public async Task<GameEngineGameState> Sync(string challengeId, CancellationToken cancellationToken)
{
var challenge = await _store
.WithNoTracking<Data.Challenge>()
.SingleOrDefaultAsync(c => c.Id == challengeId, cancellationToken);

if (challenge is null)
{
return null;
}

var state = await _gameEngine.GetChallengeState(GameEngineType.TopoMojo, challenge.State);
await Sync(challenge, state, _actingUser.Get()?.Id, cancellationToken);

return await _gameEngine.GetChallengeState(GameEngineType.TopoMojo, challenge.State);
}

public Task Sync(Data.Challenge challenge, GameEngineGameState state, string actingUserId, CancellationToken cancellationToken)
=> Sync(cancellationToken, new SyncEntry(actingUserId, challenge, state));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ public interface IEnrollmentReportService
Task<EnrollmentReportStatSummary> GetSummaryStats(EnrollmentReportParameters parameters, CancellationToken cancellationToken);
}

internal class EnrollmentReportService(
IReportsService reportsService,
internal class EnrollmentReportService(IReportsService reportsService,
IStore store
) : IEnrollmentReportService
{
Expand All @@ -32,8 +31,8 @@ IStore store
var seriesCriteria = _reportsService.ParseMultiSelectCriteria(parameters.Series);
var sponsorCriteria = _reportsService.ParseMultiSelectCriteria(parameters.Sponsors);
var trackCriteria = _reportsService.ParseMultiSelectCriteria(parameters.Tracks);
DateTimeOffset? enrollDateStart = parameters.EnrollDateStart.HasValue ? parameters.EnrollDateStart.Value.ToEndDate().ToUniversalTime() : null;
DateTimeOffset? enrollDateEnd = parameters.EnrollDateEnd.HasValue ? parameters.EnrollDateEnd.Value.ToEndDate().ToUniversalTime() : null;
var enrollDateStart = parameters.EnrollDateStart.HasValue ? parameters.EnrollDateStart.Value.ToEndDate().ToUniversalTime() : default(DateTimeOffset?);
var enrollDateEnd = parameters.EnrollDateEnd.HasValue ? parameters.EnrollDateEnd.Value.ToEndDate().ToUniversalTime() : default(DateTimeOffset?);

// the fundamental unit of reporting here is really the player record (an "enrollment"), so resolve enrollments that
// meet the filter criteria (and have at least one challenge completed in competitive mode)
Expand Down

0 comments on commit 4f5473c

Please sign in to comment.