def auction_with_a_winner(input_dto: WithdrawingBidsInputDto) -> Auction: losing_bid = Bid(id=4, bidder_id=2, amount=get_dollars('5.50')) winning_bid = Bid(id=2, bidder_id=1, amount=get_dollars('6.00')) return Auction(id=2, title='does not matter', initial_price=get_dollars('5.00'), bids=[winning_bid, losing_bid])
def test_should_return_highest_bid_for_current_price(): auction = create_auction(bids=[ Bid(id=1, bidder_id=1, amount=get_dollars('20')), Bid(id=2, bidder_id=2, amount=get_dollars('15')), ]) assert auction.current_price == get_dollars('20')
def test_saves_auction_changes( connection: Connection, another_bidder_id: int, bid_model: RowProxy, auction_model_with_a_bid: RowProxy, ends_at: datetime, event_bus_mock: Mock, ) -> None: new_bid_price = get_dollars(bid_model.amount * 2) auction = Auction( id=auction_model_with_a_bid.id, title=auction_model_with_a_bid.title, starting_price=get_dollars(auction_model_with_a_bid.starting_price), ends_at=ends_at, bids=[ Bid(bid_model.id, bid_model.bidder_id, get_dollars(bid_model.amount)), Bid(None, another_bidder_id, new_bid_price), ], ended=True, ) SqlAlchemyAuctionsRepo(connection, event_bus_mock).save(auction) assert connection.execute(select([func.count() ]).select_from(bids)).scalar() == 2 proxy = connection.execute( select([ auctions ]).where(auctions.c.id == auction_model_with_a_bid.id)).first() assert proxy.current_price == new_bid_price.amount assert proxy.ended
def test_should_return_highest_bids_user_id_for_winners_list(): auction = create_auction(bids=[ Bid(id=1, bidder_id=1, amount=get_dollars('101')), Bid(id=2, bidder_id=2, amount=get_dollars('15')), Bid(id=3, bidder_id=3, amount=get_dollars('100')), ]) assert auction.winners == [1]
def test_should_not_be_winning_if_bid_lower_than_current_price() -> None: auction = create_auction(bids=[ Bid(id=1, bidder_id=1, amount=get_dollars('10.00')) ]) lower_bid = Bid(id=None, bidder_id=2, amount=get_dollars('5.00')) auction.make_a_bid(lower_bid) assert lower_bid.bidder_id not in auction.winners
def test_should_return_highest_bids_user_id_for_winners_list() -> None: auction = AuctionFactory( bids=[ Bid(id=1, bidder_id=1, amount=get_dollars("101")), Bid(id=2, bidder_id=2, amount=get_dollars("15")), Bid(id=3, bidder_id=3, amount=get_dollars("100")), ] ) assert auction.winners == [1]
def test_should_emit_auction_ended(yesterday: datetime) -> None: auction = AuctionFactory(bids=[Bid(id=1, bidder_id=1, amount=get_dollars("15.00"))], ends_at=yesterday) auction.end_auction() expected_event = AuctionEnded(auction.id, auction.winners[0], auction.current_price, auction.title) assert auction.domain_events == [expected_event]
def test_saves_auction_changes(auction_model_with_a_bid: AuctionModel) -> None: bid_model = auction_model_with_a_bid.bid_set.first() auction = Auction(id=auction_model_with_a_bid.id, title=auction_model_with_a_bid.title, initial_price=get_dollars( auction_model_with_a_bid.initial_price), bids=[ Bid(bid_model.id, bid_model.bidder_id, get_dollars(bid_model.amount)), Bid(None, bid_model.bidder_id, get_dollars(bid_model.amount)) ]) DjangoORMAuctionsRepository().save(auction) assert auction_model_with_a_bid.bid_set.count() == 2
def test_should_withdraw_the_only_bid() -> None: auction = AuctionFactory(bids=[Bid(id=1, bidder_id=1, amount=get_dollars("50"))]) auction.withdraw_bids([1]) assert auction.winners == [] assert auction.current_price == auction.starting_price
def test_should_not_be_winning_if_bid_lower_than_current_price() -> None: auction = AuctionFactory(bids=[Bid(id=1, bidder_id=1, amount=get_dollars("10.00"))]) lower_bid_bidder_id = 2 auction.place_bid(bidder_id=lower_bid_bidder_id, amount=get_dollars("5.00")) assert lower_bid_bidder_id not in auction.winners
def test_should_add_withdrawn_bids_ids_to_separate_list(): auction = create_auction(bids=[ Bid(id=1, bidder_id=1, amount=get_dollars('50')) ]) auction.withdraw_bids([1]) assert auction.withdrawn_bids_ids == [1]
def test_makes_an_expected_bid(input_dto: PlacingBidInputDto, auction: Auction) -> None: with patch.object(Auction, 'make_a_bid', wraps=auction.make_a_bid) as make_a_bid_mock: PlacingBidUseCase().execute(input_dto) make_a_bid_mock.assert_called_once_with( Bid(id=None, amount=input_dto.amount, bidder_id=input_dto.bidder_id))
def test_should_withdraw_the_only_bid(): auction = create_auction(bids=[ Bid(id=1, bidder_id=1, amount=get_dollars('50')) ]) auction.withdraw_bids([1]) assert auction.winners == [] assert auction.current_price == auction.initial_price
def test_should_emit_event_upon_overbid() -> None: bid_that_will_lose = Bid(id=1, bidder_id=1, amount=get_dollars("15.00")) auction = AuctionFactory(bids=[bid_that_will_lose]) new_bid_amount = get_dollars("20.00") auction.place_bid(bidder_id=2, amount=new_bid_amount) expected_event = BidderHasBeenOverbid(auction.id, bid_that_will_lose.bidder_id, new_bid_amount, auction.title) assert expected_event in auction.domain_events
def test_should_emit_winning_if_overbids() -> None: auction = AuctionFactory(bids=[Bid(id=1, bidder_id=1, amount=get_dollars("15.00"))]) winning_amount = auction.current_price + get_dollars("1.00") auction.place_bid(bidder_id=2, amount=winning_amount) expected_winning_event = WinningBidPlaced(auction.id, 2, winning_amount, auction.title) expected_overbid_event = BidderHasBeenOverbid(auction.id, 1, winning_amount, auction.title) assert auction.domain_events == [expected_winning_event, expected_overbid_event]
def get(self, auction_id: int) -> Auction: from auctions.models import Auction as AuctionModel auction_model = AuctionModel.objects.prefetch_related('bid_set').get(id=auction_id) return Auction( id=auction_model.id, title=auction_model.title, initial_price=get_dollars(auction_model.initial_price), bids=[ Bid(id=bid_model.id, bidder_id=bid_model.bidder_id, amount=get_dollars(bid_model.amount)) for bid_model in auction_model.bid_set.all() ] )
def _row_to_entity(self, auction_proxy: RowProxy, bids_proxies: List[RowProxy]) -> Auction: auction_bids = [ Bid(bid.id, bid.bidder_id, get_dollars(bid.amount)) for bid in bids_proxies ] return Auction( auction_proxy.id, auction_proxy.title, get_dollars(auction_proxy.starting_price), auction_bids, auction_proxy.ends_at.replace(tzinfo=pytz.UTC), auction_proxy.ended, )
def test_removes_withdrawn_bids( auction_model_with_a_bid: AuctionModel) -> None: bid_model = auction_model_with_a_bid.bid_set.first() auction = Auction(id=auction_model_with_a_bid.id, title=auction_model_with_a_bid.title, initial_price=get_dollars( auction_model_with_a_bid.initial_price), bids=[ Bid(bid_model.id, bid_model.bidder_id, get_dollars(bid_model.amount)), ]) auction.withdrawn_bids_ids = [bid_model.id] DjangoORMAuctionsRepository().save(auction) assert auction_model_with_a_bid.bid_set.count() == 0
def execute(self, input_dto: PlacingBidInputDto) -> None: auction = self.auctions_repo.get(input_dto.auction_id) bid = Bid(id=None, bidder_id=input_dto.bidder_id, amount=input_dto.amount) auction.make_a_bid(bid) self.auctions_repo.save(auction) if input_dto.bidder_id in auction.winners: self.email_gateway.notify_about_winning_auction( auction.id, input_dto.bidder_id) output_dto = PlacingBidOutputDto( input_dto.bidder_id in auction.winners, auction.current_price) self.presenter.present(output_dto)
def test_gets_existing_auction( connection: Connection, auction_model_with_a_bid: RowProxy, bid_model: RowProxy, ends_at: datetime, event_bus_mock: Mock, ) -> None: auction = SqlAlchemyAuctionsRepo(connection, event_bus_mock).get( auction_model_with_a_bid.id) assert auction.id == auction_model_with_a_bid.id assert auction.title == auction_model_with_a_bid.title assert auction.starting_price == get_dollars( auction_model_with_a_bid.starting_price) assert auction.current_price == get_dollars(bid_model.amount) assert auction.ends_at == ends_at assert set(auction.bids) == { Bid(bid_model.id, bid_model.bidder_id, get_dollars(bid_model.amount)) }
def test_removes_withdrawn_bids(connection: Connection, bid_model: RowProxy, auction_model_with_a_bid: dict, ends_at: datetime, event_bus_mock: Mock) -> None: auction = Auction( id=auction_model_with_a_bid.id, title=auction_model_with_a_bid.title, starting_price=get_dollars(auction_model_with_a_bid.starting_price), ends_at=ends_at, bids=[ Bid(bid_model.id, bid_model.bidder_id, get_dollars(bid_model.amount)) ], ended=False, ) auction.withdraw_bids([bid_model.id]) SqlAlchemyAuctionsRepo(connection, event_bus_mock).save(auction) assert connection.execute(select([func.count() ]).select_from(bids)).scalar() == 0
def test_should_win_auction_if_is_the_only_bidder_above_initial_price(): auction = create_auction() auction.make_a_bid(Bid(id=None, bidder_id=1, amount=get_dollars('11'))) assert auction.winners == [1]
def test_should_add_withdrawn_bids_ids_to_separate_list() -> None: auction = AuctionFactory(bids=[Bid(id=1, bidder_id=1, amount=get_dollars("50"))]) auction.withdraw_bids([1]) assert auction.withdrawn_bids_ids == [1]
def test_should_not_be_winning_auction_if_bids_below_initial_price(): auction = create_auction() auction.make_a_bid(Bid(id=None, bidder_id=1, amount=get_dollars('5'))) assert auction.winners == []
def test_should_return_highest_bid_for_current_price() -> None: auction = AuctionFactory( bids=[Bid(id=1, bidder_id=1, amount=get_dollars("20")), Bid(id=2, bidder_id=2, amount=get_dollars("15"))] ) assert auction.current_price == get_dollars("20")