コード例 #1
0
ファイル: user.py プロジェクト: bozbalci/bidpazari
    def create_auction(self, item_id: int, bidding_strategy_identifier: str,
                       **kwargs):
        uhi = UserHasItem.objects.get(user_id=self.id,
                                      item_id=item_id,
                                      is_sold=False)

        runtime_manager.create_auction(
            uhi=uhi,
            bidding_strategy_identifier=bidding_strategy_identifier,
            **kwargs)
        return uhi.id
コード例 #2
0
ファイル: views.py プロジェクト: bozbalci/bidpazari
    def post(self, request, *args, **kwargs):
        pk = kwargs['pk']
        item = get_object_or_404(Item, pk=pk)
        uhi = get_object_or_404(UserHasItem,
                                item=item,
                                user=request.user,
                                is_sold=False)
        bidding_strategy = request.POST.get('bidding_strategy')
        form_class = self.FORMS.get(bidding_strategy,
                                    CreateIncrementAuctionForm)
        form = form_class(request.POST)

        if form.is_valid():
            try:
                auction = runtime_manager.create_auction(
                    uhi=uhi,
                    bidding_strategy_identifier=bidding_strategy,
                    **form.cleaned_data,
                )
            except ItemAlreadyOnSale as e:
                messages.add_message(request, messages.ERROR, str(e))
            else:
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'Created the auction! If the below details look correct to you, hit start and let the games begin!',
                )
                return redirect(
                    reverse('auction-details', kwargs={'pk': auction.id}))

        return render(
            request,
            'core/create_auction_confirm.html',
            {
                'form': form,
                'bidding_strategy': bidding_strategy,
                'item': item
            },
        )
コード例 #3
0
    def test_highest_contribution_bidding_maximum_price(self):
        john = RuntimeUser(
            username="******",
            email="*****@*****.**",
            password_raw="11441144",
            first_name="John",
            last_name="Sims",
        )
        jimmy = RuntimeUser(
            username="******",
            email="*****@*****.**",
            password_raw="12345678",
            first_name="James",
            last_name="Hetfield",
        )
        jack = RuntimeUser(
            username="******",
            email="*****@*****.**",
            password_raw="i_secretly_like_johnny_walker",
            first_name="Jack",
            last_name="Daniels",
        )

        john.persist()
        jimmy.persist()
        jack.persist()

        john.connect()
        jimmy.connect()
        jack.connect()

        john.add_balance_transaction(Decimal(150.00))
        jimmy.add_balance_transaction(Decimal(140.00))
        jack.add_balance_transaction(Decimal(130.00))

        scarf = Item.objects.create(title="Scarf",
                                    description="A really cool scarf",
                                    item_type="Clothing")
        jimmy_has_scarf = UserHasItem.objects.create(
            item=scarf, user=jimmy.persistent_user)

        auction = runtime_manager.create_auction(
            uhi=jimmy_has_scarf,
            bidding_strategy_identifier="highest_contribution",
            minimum_bid_amount=Decimal(2.00),
            maximum_price=Decimal(100),
        )

        auction.start()

        auction.bid(jack, Decimal(30.00))
        auction.bid(john, Decimal(50.00))
        auction.bid(jack, Decimal(30.00))

        print(auction.auction_report)
        print(auction.auction_history)

        john.persistent_user.refresh_from_db()
        jimmy.persistent_user.refresh_from_db()
        jack.persistent_user.refresh_from_db()
        jimmy_has_scarf.refresh_from_db()

        john.disconnect()
        jimmy.disconnect()
        jack.disconnect()

        self.assertTrue(jimmy_has_scarf.is_sold)
        self.assertEqual(john.initial_balance, Decimal(100))
        self.assertEqual(jimmy.initial_balance, Decimal(250))
        self.assertEqual(jack.initial_balance, Decimal(70))
        self.assertEqual(john.persistent_user.balance, Decimal(100))
        self.assertEqual(jimmy.persistent_user.balance, Decimal(250))
        self.assertEqual(jack.persistent_user.balance, Decimal(70))
コード例 #4
0
    def test_decrement_bidding_with_no_winners(self):
        pass
        john = RuntimeUser(
            username="******",
            email="*****@*****.**",
            password_raw="11441144",
            first_name="John",
            last_name="Sims",
        )
        jimmy = RuntimeUser(
            username="******",
            email="*****@*****.**",
            password_raw="12345678",
            first_name="James",
            last_name="Hetfield",
        )

        john.persist()
        jimmy.persist()

        john.connect()
        jimmy.connect()

        john.add_balance_transaction(Decimal(100.00))
        jimmy.add_balance_transaction(Decimal(40.00))

        scarf = Item.objects.create(title="Scarf",
                                    description="A really cool scarf",
                                    item_type="Clothing")
        jimmy_has_scarf = UserHasItem.objects.create(
            item=scarf, user=jimmy.persistent_user)

        auction = runtime_manager.create_auction(
            uhi=jimmy_has_scarf,
            bidding_strategy_identifier="decrement",
            initial_price=Decimal(150.00),
            price_decrement_rate=Decimal(50.00),
            tick_ms=20,
        )

        auction.start()

        self.assertEqual(auction.bidding_strategy.get_current_price(),
                         Decimal(150.00))
        sleep(25 / 1000)
        self.assertEqual(auction.bidding_strategy.get_current_price(),
                         Decimal(100.00))
        sleep(25 / 1000)
        self.assertEqual(auction.bidding_strategy.get_current_price(),
                         Decimal(50.00))
        sleep(25 / 1000)
        self.assertEqual(auction.bidding_strategy.get_current_price(),
                         Decimal(0.00))
        sleep(250 / 1000)

        print(auction.auction_report)
        print(auction.auction_history)

        john.persistent_user.refresh_from_db()
        jimmy.persistent_user.refresh_from_db()
        jimmy_has_scarf.refresh_from_db()

        john.disconnect()
        jimmy.disconnect()

        self.assertFalse(jimmy_has_scarf.is_sold)
        self.assertEqual(john.initial_balance, Decimal(100))
        self.assertEqual(jimmy.initial_balance, Decimal(40))
        self.assertEqual(john.persistent_user.balance, Decimal(100))
        self.assertEqual(jimmy.persistent_user.balance, Decimal(40))
コード例 #5
0
    def test_decrement_bidding_and_auction_watching(self):
        john = RuntimeUser(
            username="******",
            email="*****@*****.**",
            password_raw="11441144",
            first_name="John",
            last_name="Sims",
        )
        jimmy = RuntimeUser(
            username="******",
            email="*****@*****.**",
            password_raw="12345678",
            first_name="James",
            last_name="Hetfield",
        )

        jimmy.watch_method = lambda *args, **kwargs: None
        patcher = patch.object(jimmy, "watch_method")
        m_jimmy_watch_method = patcher.start()

        john.persist()
        jimmy.persist()

        john.connect()
        jimmy.connect()

        john.add_balance_transaction(Decimal(100.00))
        jimmy.add_balance_transaction(Decimal(40.00))

        scarf = Item.objects.create(title="Scarf",
                                    description="A really cool scarf",
                                    item_type="Clothing")
        jimmy_has_scarf = UserHasItem.objects.create(
            item=scarf, user=jimmy.persistent_user)

        auction = runtime_manager.create_auction(
            uhi=jimmy_has_scarf,
            bidding_strategy_identifier="decrement",
            initial_price=Decimal(150.00),
            price_decrement_rate=Decimal(25.00),
            tick_ms=200,
        )

        auction.register_user_to_updates(jimmy.watch_method)  # this is mocked

        auction.start()

        self.assertEqual(auction.bidding_strategy.get_current_price(),
                         Decimal(150.00))
        with self.assertRaises(InsufficientBalanceError):
            auction.bid(
                john
            )  # no amount means that user is bidding to the current price
        sleep(250 / 1000)
        self.assertEqual(auction.bidding_strategy.get_current_price(),
                         Decimal(125.00))
        sleep(250 / 1000)
        self.assertEqual(auction.bidding_strategy.get_current_price(),
                         Decimal(100.00))
        auction.bid(john)  # this terminates the auction

        m_jimmy_watch_method.assert_has_calls([
            call(event_type="auction_started"),
            call(event_type="price_decremented", new_price=Decimal(125.00)),
            call(event_type="price_decremented", new_price=Decimal(100.00)),
            call(event_type="bid_received"),
            # TODO Fix this some day
            call(event_type="price_decremented", new_price=Decimal(75.00)),
            call(event_type="auction_stopped"),
        ])

        print(auction.auction_report)
        print(auction.auction_history)

        john.persistent_user.refresh_from_db()
        jimmy.persistent_user.refresh_from_db()
        jimmy_has_scarf.refresh_from_db()

        john.disconnect()
        jimmy.disconnect()

        self.assertTrue(jimmy_has_scarf.is_sold)
        self.assertEqual(john.initial_balance, Decimal(0))
        self.assertEqual(jimmy.initial_balance, Decimal(140))
        self.assertEqual(john.persistent_user.balance, Decimal(0))
        self.assertEqual(jimmy.persistent_user.balance, Decimal(140))

        patcher.stop()
コード例 #6
0
    def test_increment_bidding_exceptions(self):
        john = RuntimeUser(
            username="******",
            email="*****@*****.**",
            password_raw="11441144",
            first_name="John",
            last_name="Sims",
        )
        jimmy = RuntimeUser(
            username="******",
            email="*****@*****.**",
            password_raw="12345678",
            first_name="James",
            last_name="Hetfield",
        )
        jack = RuntimeUser(
            username="******",
            email="*****@*****.**",
            password_raw="i_secretly_like_johnny_walker",
            first_name="Jack",
            last_name="Daniels",
        )

        john.persist()
        jimmy.persist()
        jack.persist()

        john.connect()
        jimmy.connect()
        jack.connect()

        john.add_balance_transaction(Decimal(50.00))
        jimmy.add_balance_transaction(Decimal(40.00))
        jack.add_balance_transaction(Decimal(30.00))

        scarf = Item.objects.create(title="Scarf",
                                    description="A really cool scarf",
                                    item_type="Clothing")
        jimmy_has_scarf = UserHasItem.objects.create(
            item=scarf, user=jimmy.persistent_user)

        auction = runtime_manager.create_auction(
            uhi=jimmy_has_scarf,
            bidding_strategy_identifier="increment",
            initial_price=Decimal(5.00),
            minimum_increment=Decimal(2.00),
            maximum_price=Decimal(15.00),
        )

        # Cannot bid while auction is closed
        with self.assertRaises(BiddingNotAllowed) as cm:
            auction.bid(john, Decimal(123.00))
        self.assertEqual(cm.exception.reason, BiddingErrorReason.AuctionClosed)

        auction.start()

        # Cannot bid in own auction
        with self.assertRaises(BiddingNotAllowed) as cm:
            auction.bid(jimmy, Decimal(1.00))
        self.assertEqual(cm.exception.reason, BiddingErrorReason.OwnAuction)

        # Lower than initial price
        with self.assertRaises(BiddingNotAllowed) as cm:
            auction.bid(john, Decimal(1.00))
        self.assertEqual(cm.exception.reason,
                         BiddingErrorReason.InsufficientAmount)

        # Lower than minimum increment
        with self.assertRaises(BiddingNotAllowed) as cm:
            auction.bid(john, Decimal(6.00))
        self.assertEqual(cm.exception.reason,
                         BiddingErrorReason.InsufficientAmount)

        # Higher than reservable balance
        with self.assertRaises(InsufficientBalanceError):
            auction.bid(john, Decimal(666.00))

        # Happy path
        auction.bid(john, Decimal(7.00))
        self.assertEqual(john.reservable_balance, Decimal(43.00))
        auction.bid(john, Decimal(50.00))  # This closes the auction.
        self.assertEqual(john.reservable_balance, Decimal(0.00))

        print(auction.auction_report)
        print(auction.auction_history)

        # Cannot bid while auction is closed
        with self.assertRaises(BiddingNotAllowed) as cm:
            auction.bid(john, Decimal(123.00))
        self.assertEqual(cm.exception.reason, BiddingErrorReason.AuctionClosed)

        john.persistent_user.refresh_from_db()
        jimmy.persistent_user.refresh_from_db()
        jack.persistent_user.refresh_from_db()
        jimmy_has_scarf.refresh_from_db()

        john.disconnect()
        jimmy.disconnect()
        jack.disconnect()

        self.assertTrue(jimmy_has_scarf.is_sold)
        self.assertEqual(john.initial_balance, Decimal(0))
        self.assertEqual(jimmy.initial_balance, Decimal(90))
        self.assertEqual(jack.initial_balance, Decimal(30))
        self.assertEqual(john.persistent_user.balance, Decimal(0))
        self.assertEqual(jimmy.persistent_user.balance, Decimal(90))
        self.assertEqual(jack.persistent_user.balance, Decimal(30))