Skip to content

Commit

Permalink
v3.24.0 (#525)
Browse files Browse the repository at this point in the history
* Remove unnecessary exception nonsense

* Add fields to challenges report

* Partially address #254 - allow alt names on certificates

* MInor bug fixes

* Fix name settings bug

* Cleanup

* Fix team session start bug

* Unit test for ToLookup and snippet update

* Tests

* Add initial tests
  • Loading branch information
sei-bstein authored Nov 8, 2024
1 parent 8211bb5 commit f7c9244
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public static async Task ShouldYieldGameboardValidationException<T>(this Task<Ht
var response = await request;
var responseContent = await response.Content.ReadAsStringAsync();


if (!IsExceptionString<T>(responseContent))
throw new WrongExceptionType(typeof(T), responseContent);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using Gameboard.Api.Common;
using Gameboard.Api.Structure;

namespace Gameboard.Api.Tests.Integration.Teams;

public class TeamControllerStartTeamSessionTests(GameboardTestContext testContext) : IClassFixture<GameboardTestContext>
{
private readonly GameboardTestContext _testContext = testContext;

[Theory, GbIntegrationAutoData]
public async Task TeamGame_WithSinglePlayer_CantStart
(
string gameId,
string playerId,
string userId,
IFixture fixture
)
{
// given a team game and a registered player with no teammates
await _testContext.WithDataState(state =>
{
state.Add(new Data.Game
{
Id = gameId,
MinTeamSize = 2,
MaxTeamSize = 5,
GameStart = DateTimeOffset.UtcNow,
GameEnd = DateTimeOffset.UtcNow.AddDays(1),
Mode = GameEngineMode.Standard,
Players = state.Build<Data.Player>(fixture, p =>
{
p.Id = playerId;
p.User = state.Build<Data.User>(fixture, u => u.Id = userId);
}).ToCollection()
});
});

// when they try to start their session
await _testContext
.CreateHttpClientWithActingUser(u => u.Id = userId)
.PutAsync($"api/player/{playerId}/start", null)
// they should get a validation error
.ShouldYieldGameboardValidationException<GameboardAggregatedValidationExceptions>();
}

[Theory, GbIntegrationAutoData]
public async Task TeamGame_WithTwoPlayers_CanStart
(
string gameId,
string playerId,
string userId,
string teamId,
IFixture fixture
)
{
// given a team game and a registered player with no teammates
await _testContext.WithDataState(state =>
{
state.Add(new Data.Game
{
Id = gameId,
MinTeamSize = 2,
MaxTeamSize = 5,
GameStart = DateTimeOffset.UtcNow,
GameEnd = DateTimeOffset.UtcNow.AddDays(1),
Mode = GameEngineMode.Standard,
Players =
[
state.Build<Data.Player>(fixture, p =>
{
p.Id = playerId;
p.Role = PlayerRole.Manager;
p.TeamId = teamId;
p.User = state.Build<Data.User>(fixture, u => u.Id = userId);
}),
state.Build<Data.Player>(fixture, p =>
{
p.Id = fixture.Create<string>();
p.Role = PlayerRole.Member;
p.TeamId = teamId;
})
]
});
});

// when they try to start their session
var result = await _testContext
.CreateHttpClientWithActingUser(u => u.Id = userId)
.PutAsync($"api/player/{playerId}/start", null)
.DeserializeResponseAs<Player>();

//
}
}
3 changes: 3 additions & 0 deletions src/Gameboard.Api/Extensions/ExceptionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ namespace Gameboard.Api;

public static class ExceptionExtensions
{
public static string ToTypeName(string exceptionCode)
=> Encoding.UTF8.GetString(Convert.FromBase64String(exceptionCode));

public static string ToExceptionCode<T>(this T exception) where T : GameboardValidationException
=> ToExceptionCode(typeof(T));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ public async Task<Player> StartSession(SessionStartRequest model, User actor, bo
.WithNoTracking<Data.Player>()
.SingleOrDefaultAsync(p => p.Id == model.PlayerId);

var result = await _mediator.Send(new StartTeamSessionsCommand(new string[] { startingPlayer.TeamId }));
var result = await _mediator.Send(new StartTeamSessionsCommand([startingPlayer.TeamId]));

// also set the starting player's properties because we'll use them as a return
var teamStartResult = result.Teams[startingPlayer.TeamId];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ namespace Gameboard.Api.Features.Teams;

public record StartTeamSessionsCommand(IEnumerable<string> TeamIds) : IRequest<StartTeamSessionsResult>;

internal sealed class StartTeamSessionsHandler(
internal sealed class StartTeamSessionsHandler
(
IActingUserService actingUserService,
IExternalGameHostService externalGameHostService,
IGameModeServiceFactory gameModeServiceFactory,
Expand All @@ -35,7 +36,7 @@ internal sealed class StartTeamSessionsHandler(
ITeamService teamService,
IUserRolePermissionsService permissionsService,
IGameboardRequestValidator<StartTeamSessionsCommand> validator
) : IRequestHandler<StartTeamSessionsCommand, StartTeamSessionsResult>
) : IRequestHandler<StartTeamSessionsCommand, StartTeamSessionsResult>
{
private readonly User _actingUser = actingUserService.Get();
private readonly IExternalGameHostService _externalGameHostService = externalGameHostService;
Expand All @@ -59,7 +60,7 @@ public async Task<StartTeamSessionsResult> Handle(StartTeamSessionsCommand reque
// throw on cancel request so we can clean up the debris
cancellationToken.ThrowIfCancellationRequested();

_logger.LogInformation($"Gathering data for game start (teams: {request.TeamIds.ToDelimited()})", "resolving game...");
_logger.LogInformation($"Gathering data for game start (teams: {request.TeamIds.ToDelimited()})");
var teams = await _store
.WithNoTracking<Data.Player>()
.Where(p => request.TeamIds.Contains(p.TeamId))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,26 @@

namespace Gameboard.Api.Features.Teams;

internal class StartTeamSessionsValidator : IGameboardRequestValidator<StartTeamSessionsCommand>
internal class StartTeamSessionsValidator
(
IActingUserService actingUserService,
IGameService gameService,
IGameModeServiceFactory gameModeServiceFactory,
INowService now,
IUserRolePermissionsService permissionsService,
ISessionWindowCalculator sessionWindow,
IStore store,
IValidatorService<StartTeamSessionsCommand> validatorService
) : IGameboardRequestValidator<StartTeamSessionsCommand>
{
private readonly User _actingUser;
private readonly IGameModeServiceFactory _gameModeServiceFactory;
private readonly IGameService _gameService;
private readonly INowService _now;
private readonly IUserRolePermissionsService _permissionsService;
private readonly ISessionWindowCalculator _sessionWindow;
private readonly IStore _store;
private readonly IValidatorService<StartTeamSessionsCommand> _validatorService;

public StartTeamSessionsValidator
(
IActingUserService actingUserService,
IGameService gameService,
IGameModeServiceFactory gameModeServiceFactory,
INowService now,
IUserRolePermissionsService permissionsService,
ISessionWindowCalculator sessionWindow,
IStore store,
IValidatorService<StartTeamSessionsCommand> validatorService
)
{
_actingUser = actingUserService.Get();
_gameModeServiceFactory = gameModeServiceFactory;
_gameService = gameService;
_now = now;
_permissionsService = permissionsService;
_sessionWindow = sessionWindow;
_store = store;
_validatorService = validatorService;
}
private readonly User _actingUser = actingUserService.Get();
private readonly IGameModeServiceFactory _gameModeServiceFactory = gameModeServiceFactory;
private readonly IGameService _gameService = gameService;
private readonly INowService _now = now;
private readonly IUserRolePermissionsService _permissionsService = permissionsService;
private readonly ISessionWindowCalculator _sessionWindow = sessionWindow;
private readonly IStore _store = store;
private readonly IValidatorService<StartTeamSessionsCommand> _validatorService = validatorService;

public async Task Validate(StartTeamSessionsCommand request, CancellationToken cancellationToken)
{
Expand Down

0 comments on commit f7c9244

Please sign in to comment.