def test_cancel_auction_admin(initdb): datetime_now = datetime(2000, 1, 2, 3, 4, 5, tzinfo=timezone.utc) datetime_end = datetime(2000, 12, 11, 10, 9, 8, tzinfo=timezone.utc) app = create_app({ "MYSQL_CONNECT_KWARGS": testdb.MYSQL_CONNECT_KWARGS, "YAMI_ADMIN_PASSWORD": "******" }) with app.app_context(): g.datetime_now = datetime_now auction_id, _ = logic.new_auction({ "itemname": "foo", "quantity": 1, "username": "******", "datetime_end": datetime_end, "price_start": 456, "price_prompt": None, "price_step_min": 111, "location": "anyware", "description": "something", }) g.datetime_now = datetime_now + timedelta(minutes=30) result = logic.cancel_auction(auction_id, "password") auction, _ = logic.get_auction_info(auction_id, for_update=False) logic.commit() assert result == logic.CancelErrorCodes.CANCEL_OK assert auction["ended"] == 1 assert auction["endtype"] == logic.EndType.ENDTYPE_CANCELED_BY_ADMIN assert auction["datetime_update"] == datetime_now + timedelta(minutes=30)
def test_get_auction_info_notfound(): datetime_now = datetime(2000, 1, 2, 3, 4, 5, tzinfo=timezone.utc) #datetime_now_naive = datetime_now.replace(tzinfo=None) app = create_app({}) cursor_mock1 = create_cursor_mock() cursor_mock1.fetchone.return_value = None db_mock = mock.MagicMock() db_mock.cursor.side_effect = [cursor_mock1] with app.app_context(): g.datetime_now = datetime_now g.db = db_mock auction, bids = logic.get_auction_info(42, False) assert db_mock.cursor.mock_calls == [ mock.call(pymysql.cursors.DictCursor), ] assert cursor_mock1.mock_calls == [ mock.call.execute("SELECT * FROM t_auction WHERE auction_id = %s", (42, )), mock.call.fetchone(), mock.call.close(), ] assert auction == None assert bids == None
def test_cancel_auction_seller(initdb): datetime_now = datetime(2000, 1, 2, 3, 4, 5, tzinfo=timezone.utc) datetime_end = datetime(2000, 12, 11, 10, 9, 8, tzinfo=timezone.utc) app = create_app({ "MYSQL_CONNECT_KWARGS": testdb.MYSQL_CONNECT_KWARGS, }) with app.app_context(): g.datetime_now = datetime_now auction_id, password = logic.new_auction({ "itemname": "foo", "quantity": 1, "username": "******", "datetime_end": datetime_end, "price_start": 456, "price_prompt": None, "price_step_min": 111, "location": "anyware", "description": "something", }) g.datetime_now = datetime_now + timedelta(minutes=30) result = logic.cancel_auction(auction_id, password) auction, _ = logic.get_auction_info(auction_id, for_update=False) logic.commit() assert result == logic.CancelErrorCodes.CANCEL_OK assert auction["ended"] == 1 assert auction["endtype"] == logic.EndType.ENDTYPE_CANCELED_BY_SELLER assert auction["datetime_update"] == datetime_now + timedelta(minutes=30)
def test_bid_auction_manytimes(initdb): datetime_now = datetime(2000, 1, 2, 3, 4, 5, tzinfo=timezone.utc) datetime_end = datetime(2000, 12, 11, 10, 9, 8, tzinfo=timezone.utc) datetime_bid = datetime(2000, 6, 7, 8, 9, 10, tzinfo=timezone.utc) app = create_app({ "MYSQL_CONNECT_KWARGS": testdb.MYSQL_CONNECT_KWARGS, "YAMI_PRICE_STEP_MIN": 111, "YAMI_PRICE_STEP_FROM_CURRENT_PRICE": True, "YAMI_PRICE_STEP_RULE": { 1: 1, }, "YAMI_AUTO_EXTENSION": 0, }) with app.app_context(): g.datetime_now = datetime_now auction_id, _ = logic.new_auction({ "itemname": "foo", "quantity": 2, "username": "******", "datetime_end": datetime_end, "price_start": 456, "price_prompt": None, "price_step_min": 111, "location": "anyware", "description": "something", }) logic.commit() bid_results = [] with app.app_context(): for i in range(5): g.datetime_now = datetime_bid + timedelta(days=i + 1) bid_results.append( logic.bid_auction({ "auction_id": auction_id, "username": "******" + str(i), "price": 1000 * (i + 1), })) auction, bids = logic.get_auction_info(auction_id, for_update=False) auctions, _ = logic.get_auction_list(1, 0, False) logic.commit() for i in range(5): assert bid_results[i] == logic.BidErrorCodes.BID_OK assert not auction["ended"] assert auction["datetime_update"] == datetime_bid + timedelta(days=5) assert auction["price_current_low"] == 4000 assert auctions[0]["price_current_low"] == 4000 for i in range(5): assert bids[i] == { "bid_id": 5 - i, "auction_id": auction_id, "username": "******" + str(4 - i), "price": 1000 * (5 - i), "datetime_bid": datetime_bid + timedelta(days=5 - i), }
def test_get_auction_info_notfound(initdb): datetime_now = datetime(2000, 1, 2, 3, 4, 5, tzinfo=timezone.utc) app = create_app({ "MYSQL_CONNECT_KWARGS": testdb.MYSQL_CONNECT_KWARGS, }) with app.app_context(): g.datetime_now = datetime_now auction, bids = logic.get_auction_info(42, for_update=False) auctions, num_auctions = logic.get_auction_list(10, 0, False) assert auction is None assert bids is None assert len(auctions) == 0 assert num_auctions == 0
def test_bid_auction_extension(quantity, prompt, extended, initdb): datetime_now = datetime(2000, 1, 2, 3, 4, 5, tzinfo=timezone.utc) datetime_end = datetime(2000, 12, 11, 10, 9, 8, tzinfo=timezone.utc) yami_auto_extension = 3600 app = create_app({ "MYSQL_CONNECT_KWARGS": testdb.MYSQL_CONNECT_KWARGS, "YAMI_PRICE_STEP_MIN": 111, "YAMI_PRICE_STEP_FROM_CURRENT_PRICE": True, "YAMI_PRICE_STEP_RULE": { 1: 1, }, "YAMI_AUTO_EXTENSION": yami_auto_extension, }) with app.app_context(): g.datetime_now = datetime_now auction_id, _ = logic.new_auction({ "itemname": "foo", "quantity": quantity, "username": "******", "datetime_end": datetime_end, "price_start": 456, "price_prompt": 1000, "price_step_min": 111, "location": "anyware", "description": "something", }) logic.commit() with app.app_context(): g.datetime_now = datetime_end - timedelta(minutes=30) logic.bid_auction({ "auction_id": auction_id, "username": "******", "price": 1000 if prompt else 500, }) auction, _ = logic.get_auction_info(auction_id, for_update=False) logic.commit() assert auction["datetime_end"] == datetime_end + ( -timedelta(minutes=30) + timedelta(seconds=yami_auto_extension) if extended else timedelta())
def test_new_auction(initdb, monkeypatch): datetime_now = datetime(2000, 1, 2, 3, 4, 5, tzinfo=timezone.utc) datetime_end = datetime(2000, 12, 11, 10, 9, 8, tzinfo=timezone.utc) secret_token_hex_mock = mock.MagicMock() secret_token_hex_mock.return_value = "0123456789abcdef" monkeypatch.setattr(secrets, "token_hex", secret_token_hex_mock) app = create_app({ "MYSQL_CONNECT_KWARGS": testdb.MYSQL_CONNECT_KWARGS, }) with app.app_context(): g.datetime_now = datetime_now auction_id, password = logic.new_auction({ "itemname": "foo", "quantity": 123, "username": "******", "datetime_end": datetime_end, "price_start": 456, "price_prompt": 789, "price_step_min": 111, "location": "anyware", "description": "something", }) auction, bids = logic.get_auction_info(auction_id, for_update=False) held_auctions, num_held_auctions = logic.get_auction_list(10, 0, False) out_of_page_held_auctions, num_held_auctions_2 = logic.get_auction_list( 10, 10, False) ended_auctions, num_ended_auctions = logic.get_auction_list( 10, 0, True) logic.commit() expected_auction = { "auction_id": 1, "type": 1, "itemname": "foo", "quantity": 123, "username": "******", "datetime_start": datetime_now, "datetime_end": datetime_end, "datetime_update": datetime_now, "price_start": 456, "price_prompt": 789, "price_step_min": 111, "location": "anyware", "description": "something", "ended": False, "endtype": 0, "price_bid_min": 456, "price_current_high": None, "price_current_low": None, } expected_auction_in_list = expected_auction.copy() expected_auction_in_list["num_bids"] = 0 assert auction_id == 1 assert password == "0123456789abcdef" assert auction == expected_auction assert len(bids) == 0 assert held_auctions == [expected_auction_in_list] assert num_held_auctions == 1 assert len(out_of_page_held_auctions) == 0 assert num_held_auctions_2 == 1 assert len(ended_auctions) == 0 assert num_ended_auctions == 0 with app.app_context(): g.datetime_now = datetime_end auction, bids = logic.get_auction_info(auction_id, for_update=False) held_auctions, num_held_auctions = logic.get_auction_list(10, 0, False) ended_auctions, num_ended_auctions = logic.get_auction_list( 10, 0, True) logic.commit() expected_auction["ended"] = True expected_auction_in_list["ended"] = True assert auction == expected_auction assert len(bids) == 0 assert len(held_auctions) == 0 assert num_held_auctions == 0 assert ended_auctions == [expected_auction_in_list] assert num_ended_auctions == 1
def test_bid_auction_prompt(initdb): datetime_now = datetime(2000, 1, 2, 3, 4, 5, tzinfo=timezone.utc) datetime_end = datetime(2000, 12, 11, 10, 9, 8, tzinfo=timezone.utc) datetime_bid = datetime(2000, 6, 7, 8, 9, 10, tzinfo=timezone.utc) app = create_app({ "MYSQL_CONNECT_KWARGS": testdb.MYSQL_CONNECT_KWARGS, "YAMI_PRICE_STEP_MIN": 111, "YAMI_PRICE_STEP_FROM_CURRENT_PRICE": True, "YAMI_PRICE_STEP_RULE": { 1: 1, } }) with app.app_context(): g.datetime_now = datetime_now auction_id, _ = logic.new_auction({ "itemname": "foo", "quantity": 1, "username": "******", "datetime_end": datetime_end, "price_start": 456, "price_prompt": 789, "price_step_min": 111, "location": "anyware", "description": "something", }) logic.commit() with app.app_context(): g.datetime_now = datetime_bid bid_result = logic.bid_auction({ "auction_id": auction_id, "username": "******", "price": 789, }) auction, bids = logic.get_auction_info(auction_id, for_update=False) logic.commit() assert bid_result == logic.BidErrorCodes.BID_OK assert auction["ended"] assert auction["datetime_update"] == datetime_bid assert bids == [{ "bid_id": 1, "auction_id": auction_id, "username": "******", "price": 789, "datetime_bid": datetime_bid, }] with app.app_context(): g.datetime_now = datetime_bid bid_result = logic.bid_auction({ "auction_id": auction_id, "username": "******", "price": 1000, }) logic.commit() assert bid_result == logic.BidErrorCodes.BID_ERROR_ALREADY_ENDED
def test_get_auction_info_price(num_bids): datetime_now = datetime(2000, 1, 2, 3, 4, 5, tzinfo=timezone.utc) datetime_now_naive = datetime_now.replace(tzinfo=None) app = create_app({ "YAMI_PRICE_STEP_FROM_CURRENT_PRICE": False, "YAMI_PRICE_STEP_MIN": 100, "YAMI_PRICE_STEP_RULE": { 1: 1 } }) cursor_mock1 = create_cursor_mock() cursor_mock1.fetchone.return_value = { "auction_id": 42, "quantity": 3, "price_start": 10, "price_prompt": None, "price_step_min": 100, "ended": 0, "datetime_end": datetime_now_naive + timedelta(days=1), } cursor_mock2 = create_cursor_mock() cursor_mock2.fetchall.return_value = [{ "bid_id": i, "price": i * 100, "datetime_bid": datetime_now_naive - timedelta(hours=num_bids - i + 1), } for i in range(num_bids, 0, -1)] db_mock = mock.MagicMock() db_mock.cursor.side_effect = [cursor_mock1, cursor_mock2] with app.app_context(): g.datetime_now = datetime_now g.db = db_mock auction, bids = logic.get_auction_info(42, False) assert db_mock.cursor.mock_calls == [ mock.call(pymysql.cursors.DictCursor), mock.call(pymysql.cursors.DictCursor), ] assert cursor_mock1.mock_calls == [ mock.call.execute("SELECT * FROM t_auction WHERE auction_id = %s", (42, )), mock.call.fetchone(), mock.call.close(), ] assert cursor_mock2.mock_calls == [ mock.call.execute( "SELECT * FROM t_bid WHERE auction_id = %s ORDER BY price DESC, datetime_bid ASC", (42, )), mock.call.fetchall(), mock.call.close(), ] assert auction == { "auction_id": 42, "quantity": 3, "price_start": 10, "price_prompt": None, "price_step_min": 100, "ended": False, "datetime_end": datetime_now + timedelta(days=1), "price_current_high": None if num_bids == 0 else num_bids * 100, "price_current_low": None if num_bids < 3 else (num_bids - 2) * 100, "price_bid_min": 10 if num_bids < 3 else (num_bids - 1) * 100, } assert bids == [{ "bid_id": i, "price": i * 100, "datetime_bid": datetime_now - timedelta(hours=num_bids - i + 1), } for i in range(num_bids, 0, -1)] for bid in bids: assert bid["datetime_bid"].tzinfo == timezone.utc
def test_get_auction_info_query(for_update): datetime_now = datetime(2000, 1, 2, 3, 4, 5, tzinfo=timezone.utc) datetime_now_naive = datetime_now.replace(tzinfo=None) app = create_app({ "YAMI_PRICE_STEP_FROM_CURRENT_PRICE": False, "YAMI_PRICE_STEP_MIN": 100, "YAMI_PRICE_STEP_RULE": { 1: 1 } }) cursor_mock1 = create_cursor_mock() cursor_mock1.fetchone.return_value = { "auction_id": 42, "quantity": 1, "price_start": 10, "price_prompt": None, "price_step_min": 100, "ended": 0, "datetime_end": datetime_now_naive + timedelta(days=1), } cursor_mock2 = create_cursor_mock() cursor_mock2.fetchall.return_value = [{ "bid_id": 3, "price": 100, }, { "bid_id": 1, "price": 50, }] db_mock = mock.MagicMock() db_mock.cursor.side_effect = [cursor_mock1, cursor_mock2] with app.app_context(): g.datetime_now = datetime_now g.db = db_mock auction, bids = logic.get_auction_info(42, for_update) assert db_mock.cursor.mock_calls == [ mock.call(pymysql.cursors.DictCursor), mock.call(pymysql.cursors.DictCursor), ] if for_update: auction_select_decoration = " FOR UPDATE" else: auction_select_decoration = "" assert cursor_mock1.mock_calls == [ mock.call.execute( "SELECT * FROM t_auction WHERE auction_id = %s" + auction_select_decoration, (42, )), mock.call.fetchone(), mock.call.close(), ] if for_update: bid_select_decoration = " LIMIT %s" bid_select_parameters = (42, 1) else: bid_select_decoration = "" bid_select_parameters = (42, ) assert cursor_mock2.mock_calls == [ mock.call.execute( "SELECT * FROM t_bid WHERE auction_id = %s ORDER BY price DESC, datetime_bid ASC" + bid_select_decoration, bid_select_parameters), mock.call.fetchall(), mock.call.close(), ] assert auction == { "auction_id": 42, "quantity": 1, "price_start": 10, "price_prompt": None, "price_step_min": 100, "ended": False, "datetime_end": datetime_now + timedelta(days=1), "price_current_high": 100, "price_current_low": 100, "price_bid_min": 200, } assert bids == [{ "bid_id": 3, "price": 100, }, { "bid_id": 1, "price": 50, }]