예제 #1
0
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)
예제 #2
0
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
예제 #3
0
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)
예제 #4
0
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),
        }
예제 #5
0
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
예제 #6
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())
예제 #7
0
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
예제 #8
0
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
예제 #9
0
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
예제 #10
0
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,
    }]