From d3a8e53698c5c4a01e26de816088bf8afe4a7eff Mon Sep 17 00:00:00 2001 From: morkusporkus Date: Thu, 30 Jun 2022 20:25:01 -0500 Subject: [PATCH] handle empty bid lists (#100) --- src/Server/Features/FreeAgents/List.cs | 6 ++--- src/Server/Features/OfferMatching/List.cs | 9 +++----- src/Server/Models/Bid.cs | 7 +++--- src/Server/Models/Player.cs | 2 ++ src/Tests/Features/OfferMatching/ListTests.cs | 23 +++++++++++++++++++ src/Tests/Models/PlayerTests.cs | 16 +++++++++++++ 6 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/Server/Features/FreeAgents/List.cs b/src/Server/Features/FreeAgents/List.cs index 7382c6d..be7f53e 100644 --- a/src/Server/Features/FreeAgents/List.cs +++ b/src/Server/Features/FreeAgents/List.cs @@ -75,11 +75,9 @@ public ListMappingProfile() .ForMember(d => d.Team, mo => mo.MapFrom(s => s.Team != null ? s.Team.Name : string.Empty)) .ForMember(d => d.CurrentUserIsHighestBidder, mo => mo.MapFrom(s => s.Bids.Any() && - s.Bids.GetHighestBid().TeamId == currentUserTeamId) + s.Bids.FindHighestBid()!.TeamId == currentUserTeamId) ) .ForMember(d => d.BiddingEnds, mo => mo.MapFrom(s => s.EndOfFreeAgency!.Value)) - .ForMember(d => d.HighestBid, mo => mo.MapFrom(s => s.Bids.Any() - ? s.Bids.GetHighestBid().Amount : 0) - ); + .ForMember(d => d.HighestBid, mo => mo.MapFrom(s => s.GetHighestBidAmount())); } } diff --git a/src/Server/Features/OfferMatching/List.cs b/src/Server/Features/OfferMatching/List.cs index 8022f94..1beb3db 100644 --- a/src/Server/Features/OfferMatching/List.cs +++ b/src/Server/Features/OfferMatching/List.cs @@ -56,6 +56,7 @@ public async Task Handle(ListQuery request, Cancellatio var currentUserTeamId = _httpContextAccessor.HttpContext!.User.GetTeamId(); var offerMatches = await _dbContext.Players + .Include(p => p.Bids) .Where(p => p.TeamId == currentUserTeamId) .WhereIsOfferMatching() .ProjectTo(_mapper.ConfigurationProvider) @@ -69,15 +70,11 @@ public async Task Handle(ListQuery request, Cancellatio } public class ListMappingProfile : Profile { - private const int _minimumBid = 1; public ListMappingProfile() { CreateMap() .ForMember(d => d.OfferingTeam, mo => mo.MapFrom(s => s.Team != null ? s.Team.Name : string.Empty)) - .ForMember(d => d.Offer, mo => mo.MapFrom(s => - s.Bids.Any() - ? s.Bids.GetHighestBid().Amount : _minimumBid) - ); + .ForMember(d => d.Offer, mo => mo.MapFrom(s => s.GetHighestBidAmount())); } } public record MatchPlayerCommand(int PlayerId) : IRequest { } @@ -97,7 +94,7 @@ public async Task Handle(MatchPlayerCommand request, CancellationToken can .AsTracking() .Include(p => p.Bids) .SingleAsync(p => p.Id == request.PlayerId, cancellationToken)); - player.ContractValue = player.Bids.GetHighestBid().Amount; + player.ContractValue = player.Bids.FindHighestBid()?.Amount ?? Bid.MinimumAmount; player.SetToUnsigned(); await _dbContext.SaveChangesAsync(cancellationToken); diff --git a/src/Server/Models/Bid.cs b/src/Server/Models/Bid.cs index 1608f6a..7828a96 100644 --- a/src/Server/Models/Bid.cs +++ b/src/Server/Models/Bid.cs @@ -2,6 +2,8 @@ public record Bid : BaseEntity { + public const int MinimumAmount = 1; + public Bid(int amount, int teamId, int playerId) { PlayerId = playerId; @@ -13,13 +15,12 @@ public Bid(int amount, int teamId, int playerId) public int PlayerId { get; private set; } public int TeamId { get; private set; } public DateTime CreatedOn { get; private set; } = DateTime.Now; - public Team Team { get; private set; } = null!; public Player Player { get; private set; } = null!; } public static class BidExtensions { - public static Bid GetHighestBid(this ICollection bids) - => bids.OrderByDescending(b => b.Amount).First(); + public static Bid? FindHighestBid(this ICollection bids) + => bids.OrderByDescending(b => b.Amount).FirstOrDefault(); } diff --git a/src/Server/Models/Player.cs b/src/Server/Models/Player.cs index 594779b..31f87a9 100644 --- a/src/Server/Models/Player.cs +++ b/src/Server/Models/Player.cs @@ -89,6 +89,8 @@ public Fine AddFine(decimal amount, string reason) return fine; } + public int GetHighestBidAmount() => Bids.Any() ? Bids.FindHighestBid()!.Amount : Bid.MinimumAmount; + private bool IsEligibleForFreeAgencyExtension(int teamId) { var isBidByTheSameTeam = teamId == TeamId; diff --git a/src/Tests/Features/OfferMatching/ListTests.cs b/src/Tests/Features/OfferMatching/ListTests.cs index 4ffa0dc..f6fd65a 100644 --- a/src/Tests/Features/OfferMatching/ListTests.cs +++ b/src/Tests/Features/OfferMatching/ListTests.cs @@ -91,6 +91,29 @@ public async Task GivenAnyAuthenticatedUser_WhenPlayerIsMatched_ThenPlayerIsMove result.YearAcquired.Should().Be(DateTime.Today.Year); result.ContractValue.Should().Be(int.MaxValue); } + + [Fact] + public async Task GivenAnyAuthenticatedUser_WhenPlayerHasNoBids_ThenContractValueIsOne() + { + int minimumBid = 1; + var application = CreateUserAuthenticatedApplication(); + var team = CreateFakeTeam(); + await application.AddAsync(team); + + var player = CreateFakePlayer(); + player.YearContractExpires = DateTime.MaxValue.Year; + await application.AddAsync(player); + + var request = AutoFaker.Generate(); + request.PlayerId = player.Id; + var client = application.CreateClient(); + + await client.PostAsJsonAsync(OfferMatchingListRouteFactory.Uri, request); + + var result = await application.FirstOrDefaultAsync(); + result!.ContractValue.Should().Be(minimumBid); + + } } public class ListClientTests : UITestBase diff --git a/src/Tests/Models/PlayerTests.cs b/src/Tests/Models/PlayerTests.cs index 3a925c6..064959a 100644 --- a/src/Tests/Models/PlayerTests.cs +++ b/src/Tests/Models/PlayerTests.cs @@ -28,4 +28,20 @@ public void WhereIsOfferMatching_GivenAPlayer_WhenTheirFreeAgencyIsFourOrMoreDay sut.WhereIsOfferMatching().Should().NotContain(player); } + + [Fact] + public void GivenAPlayerWithNoBids_WhenFindingTheHighestBid_ThenTheHighestBidIsTheMinimumAmount() + => CreateFakePlayer() + .GetHighestBidAmount() + .Should().Be(Bid.MinimumAmount); + + [Fact] + public void GivenAPlayerWithABid_ThenReturnsThatBidAmount() + { + var player = CreateFakePlayer(); + + player.AddBid(int.MaxValue, int.MaxValue); + + player.GetHighestBidAmount().Should().Be(int.MaxValue); + } }