Skip to content

Commit

Permalink
Return board on restore success
Browse files Browse the repository at this point in the history
  • Loading branch information
zysim committed Oct 16, 2024
1 parent 93a2b65 commit 2ea53b0
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 2,252 deletions.
21 changes: 12 additions & 9 deletions LeaderboardBackend.Test/Leaderboards.cs
Original file line number Diff line number Diff line change
Expand Up @@ -353,27 +353,30 @@ public async Task RestoreLeaderboard_OK()
DeletedAt = _clock.GetCurrentInstant()
};

Instant now = Instant.FromUnixTimeSeconds(1);
_clock.Reset(now);

context.Leaderboards.Add(deletedBoard);
await context.SaveChangesAsync();
deletedBoard.Id.Should().NotBe(default);

HttpResponseMessage res = await _apiClient.Put($"/leaderboard/{deletedBoard.Id}/restore", new()
_clock.AdvanceMinutes(1);

LeaderboardViewModel res = await _apiClient.Put<LeaderboardViewModel>($"/leaderboard/{deletedBoard.Id}/restore", new()
{
Jwt = _jwt
});

res.StatusCode.Should().Be(HttpStatusCode.NoContent);
context.ChangeTracker.Clear();
Leaderboard? board = await context.Leaderboards.FindAsync(deletedBoard.Id);
board.Should().NotBeNull();
// TODO: `DeletedAt` is still not null here. Don't know how to fix it.
board!.DeletedAt.Should().BeNull();
res.Id.Should().Be(deletedBoard.Id);
res.Slug.Should().Be(deletedBoard.Slug);
res.UpdatedAt.Should().Be(res.CreatedAt + Duration.FromMinutes(1));
res.DeletedAt.Should().BeNull();
}

[Test]
public async Task RestoreLeaderboard_NotFound()
{
Func<Task<HttpResponseMessage>> act = async () => await _apiClient.Put($"/leaderboard/100/restore", new()
Func<Task<LeaderboardViewModel>> act = async () => await _apiClient.Put<LeaderboardViewModel>($"/leaderboard/100/restore", new()
{
Jwt = _jwt
});
Expand All @@ -396,7 +399,7 @@ public async Task RestoreLeaderboard_NotFound_WasNeverDeleted()
await context.SaveChangesAsync();
board.Id.Should().NotBe(default);

Func<Task<HttpResponseMessage>> act = async () => await _apiClient.Put($"/leaderboard/{board.Id}/restore", new()
Func<Task<LeaderboardViewModel>> act = async () => await _apiClient.Put<LeaderboardViewModel>($"/leaderboard/{board.Id}/restore", new()
{
Jwt = _jwt
});
Expand Down
4 changes: 2 additions & 2 deletions LeaderboardBackend.Test/TestApi/TestApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ public async Task<TResponse> Get<TResponse>(string endpoint, HttpRequestInit ini
public async Task<TResponse> Post<TResponse>(string endpoint, HttpRequestInit init) =>
await SendAndRead<TResponse>(endpoint, init with { Method = HttpMethod.Post });

public async Task<HttpResponseMessage> Put(string endpoint, HttpRequestInit init) =>
await Send(endpoint, init with { Method = HttpMethod.Put });
public async Task<TResponse> Put<TResponse>(string endpoint, HttpRequestInit init) =>
await SendAndRead<TResponse>(endpoint, init with { Method = HttpMethod.Put });

public async Task<HttpResponseMessage> Delete(string endpoint, HttpRequestInit init) =>
await Send(endpoint, init with { Method = HttpMethod.Delete });
Expand Down
11 changes: 6 additions & 5 deletions LeaderboardBackend/Controllers/LeaderboardsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public async Task<ActionResult<LeaderboardViewModel>> GetLeaderboard(long id)

[AllowAnonymous]
[HttpGet("api/leaderboard")]
[SwaggerOperation("Gets a Leaderboard by its slug.", OperationId = "getLeaderboardBySlug")]
[SwaggerOperation("Gets a leaderboard by its slug.", OperationId = "getLeaderboardBySlug")]
[SwaggerResponse(200)]
[SwaggerResponse(404)]
public async Task<ActionResult<LeaderboardViewModel>> GetLeaderboardBySlug([FromQuery, SwaggerParameter(Required = true)] string slug)
Expand Down Expand Up @@ -89,18 +89,19 @@ public async Task<ActionResult<LeaderboardViewModel>> CreateLeaderboard(

[Authorize(Policy = UserTypes.ADMINISTRATOR)]
[HttpPut("leaderboard/{id:long}/restore")]
[SwaggerResponse(201)]
[SwaggerOperation("Restores a deleted leaderboard.", OperationId = "restoreLeaderboard")]
[SwaggerResponse(200)]
[SwaggerResponse(401)]
[SwaggerResponse(403, "The requesting `User` is unauthorized to restore `Leaderboard`s.")]
[SwaggerResponse(404, "The `Leaderboard` was not found, or it wasn't deleted in the first place.")]
public async Task<ActionResult<RestoreLeaderboardResult>> RestoreLeaderboard(
public async Task<ActionResult<LeaderboardViewModel>> RestoreLeaderboard(
long id
)
{
RestoreLeaderboardResult r = await leaderboardService.RestoreLeaderboard(id);

return r.Match<ActionResult<RestoreLeaderboardResult>>(
_ => NoContent(),
return r.Match<ActionResult<LeaderboardViewModel>>(
board => Ok(LeaderboardViewModel.MapFrom(board)),
notFound => NotFound(),
neverDeleted =>
{
Expand Down
2 changes: 1 addition & 1 deletion LeaderboardBackend/Services/ILeaderboardService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ public interface ILeaderboardService
public partial class CreateLeaderboardResult : OneOfBase<Leaderboard, CreateLeaderboardConflict>;

[GenerateOneOf]
public partial class RestoreLeaderboardResult : OneOfBase<Task, LeaderboardNotFound, LeaderboardNeverDeleted>;
public partial class RestoreLeaderboardResult : OneOfBase<Leaderboard, LeaderboardNotFound, LeaderboardNeverDeleted>;
6 changes: 4 additions & 2 deletions LeaderboardBackend/Services/Impl/LeaderboardService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
using LeaderboardBackend.Models.Requests;
using LeaderboardBackend.Result;
using Microsoft.EntityFrameworkCore;
using NodaTime;
using Npgsql;

namespace LeaderboardBackend.Services;

public class LeaderboardService(ApplicationContext applicationContext) : ILeaderboardService
public class LeaderboardService(ApplicationContext applicationContext, IClock clock) : ILeaderboardService
{
public async Task<Leaderboard?> GetLeaderboard(long id) =>
await applicationContext.Leaderboards.FindAsync(id);
Expand Down Expand Up @@ -69,10 +70,11 @@ public async Task<RestoreLeaderboardResult> RestoreLeaderboard(long id)

applicationContext.Leaderboards.Update(lb);

lb.UpdatedAt = clock.GetCurrentInstant();
lb.DeletedAt = null;

await applicationContext.SaveChangesAsync();

return Task.CompletedTask;
return lb;
}
}
Loading

0 comments on commit 2ea53b0

Please sign in to comment.