def test_enable_or_create_wallet(wait_for_db_up):

    customer_xid = str(uuid.uuid4())
    data = views.initialize_customer(customer_xid)
    token = data["token"]
    customer_dict = views.get_customer_info_by_token(token)

    with pytest.raises(views.MiniWalletException, match="not found"):
        views.disable_wallet(customer_dict)

    data = views.enable_or_create(customer_dict)
    wallet_data = data["wallet"]
    assert wallet_data["customer"] == customer_xid
    assert wallet_data["status"] == "enabled"

    with pytest.raises(views.MiniWalletException, match="already enabled"):
        views.enable_or_create(customer_dict)

    data = views.disable_wallet(customer_dict)
    wallet_data = data["wallet"]
    assert wallet_data["status"] == "disabled"

    with pytest.raises(views.MiniWalletException, match="already disabled"):
        views.disable_wallet(customer_dict)

    data = views.enable_or_create(customer_dict)
    wallet_data = data["wallet"]
    assert wallet_data["customer"] == customer_xid
    assert wallet_data["status"] == "enabled"
def test_initialize_customer(wait_for_db_up):

    token = "invalid"
    customer_dict = views.get_customer_info_by_token(token)
    assert customer_dict is None

    customer_xid = str(uuid.uuid4())
    data = views.initialize_customer(customer_xid)
    token = data["token"]
    assert len(token) == 42

    customer_dict = views.get_customer_info_by_token(token)
    assert customer_dict["xid"] == customer_xid

    with pytest.raises(views.MiniWalletException, match="already initialized"):
        views.initialize_customer(customer_xid)
def test_get_balance(wait_for_db_up):

    customer_xid = str(uuid.uuid4())
    data = views.initialize_customer(customer_xid)
    token = data["token"]
    customer_dict = views.get_customer_info_by_token(token)

    with pytest.raises(views.MiniWalletException, match="not found"):
        data = views.get_balance(customer_dict)

    views.enable_or_create(customer_dict)
    views.disable_wallet(customer_dict)

    with pytest.raises(views.MiniWalletException, match="not enabled"):
        data = views.get_balance(customer_dict)
def test_deposit_money(wait_for_db_up):

    customer_xid = str(uuid.uuid4())
    data = views.initialize_customer(customer_xid)
    token = data["token"]
    customer_dict = views.get_customer_info_by_token(token)

    with pytest.raises(views.MiniWalletException, match="not found"):
        data = views.deposit_money(customer_dict, 2000000, str(uuid.uuid4()))

    views.enable_or_create(customer_dict)

    expected_total_deposit = 0
    for i in range(10):
        amount = random.randint(1, 9) * 1000 * 1000 * 1000 * 1000
        expected_total_deposit += amount
        reference_id = str(uuid.uuid4())
        data = views.deposit_money(customer_dict, amount, reference_id)
        deposit_data = data["deposit"]
        assert deposit_data["status"] == "completed"

    data = views.get_balance(customer_dict)
    wallet_data = data["wallet"]
    assert wallet_data["balance"] == expected_total_deposit

    amount = 3 * 1000 * 1000
    reference_id = str(uuid.uuid4())
    data = views.deposit_money(customer_dict, amount, reference_id)
    deposit_data = data["deposit"]
    assert deposit_data["status"] == "completed"
    with pytest.raises(views.MiniWalletException, match="duplicate reference_id"):
        amount = 2 * 1000 * 1000
        data = views.deposit_money(customer_dict, amount, reference_id)

    for amount in [-1, 0]:
        with pytest.raises(views.MiniWalletException, match="must be positive"):
            reference_id = str(uuid.uuid4())
            data = views.deposit_money(customer_dict, amount, reference_id)

    views.disable_wallet(customer_dict)
    amount = 3 * 1000 * 1000
    reference_id = str(uuid.uuid4())
    with pytest.raises(views.MiniWalletException, match="not enabled"):
        data = views.deposit_money(customer_dict, amount, reference_id)
def test_withdraw_money(wait_for_db_up):

    customer_xid = str(uuid.uuid4())
    data = views.initialize_customer(customer_xid)
    token = data["token"]
    customer_dict = views.get_customer_info_by_token(token)

    with pytest.raises(views.MiniWalletException, match="not found"):
        data = views.withdraw_money(customer_dict, 2000000, str(uuid.uuid4()))

    views.enable_or_create(customer_dict)

    deposit_amount = 3 * 1000
    reference_id = str(uuid.uuid4())
    data = views.deposit_money(customer_dict, deposit_amount, reference_id)
    deposit_data = data["deposit"]
    assert deposit_data["status"] == "completed"

    withdrawal_amount = 2 * 1000
    reference_id = str(uuid.uuid4())
    data = views.withdraw_money(customer_dict, withdrawal_amount, reference_id)
    deposit_data = data["withdrawal"]
    assert deposit_data["status"] == "completed"

    remaining_balance = deposit_amount - withdrawal_amount
    data = views.get_balance(customer_dict)
    wallet_data = data["wallet"]
    assert wallet_data["balance"] == remaining_balance

    withdrawal_amount = remaining_balance + 1
    reference_id = str(uuid.uuid4())
    with pytest.raises(views.MiniWalletException, match="insufficient fund"):
        data = views.withdraw_money(customer_dict, withdrawal_amount, reference_id)

    reference_id = str(uuid.uuid4())
    data = views.withdraw_money(customer_dict, remaining_balance, reference_id)
    deposit_data = data["withdrawal"]
    assert deposit_data["status"] == "completed"

    data = views.get_balance(customer_dict)
    wallet_data = data["wallet"]
    assert wallet_data["balance"] == 0

    for amount in [-1, 0]:
        reference_id = str(uuid.uuid4())
        with pytest.raises(views.MiniWalletException, match="must be positive"):
            data = views.withdraw_money(customer_dict, amount, reference_id)

    deposit_amount = 3 * 1000
    reference_id = str(uuid.uuid4())
    data = views.deposit_money(customer_dict, deposit_amount, reference_id)
    deposit_data = data["deposit"]
    assert deposit_data["status"] == "completed"

    withdrawal_amount = 1 * 1000
    with pytest.raises(views.MiniWalletException, match="duplicate reference_id"):
        data = views.withdraw_money(customer_dict, withdrawal_amount, reference_id)

    views.disable_wallet(customer_dict)
    withdrawal_amount = 2 * 1000 * 1000
    reference_id = str(uuid.uuid4())
    with pytest.raises(views.MiniWalletException, match="not enabled"):
        data = views.withdraw_money(customer_dict, withdrawal_amount, reference_id)