fix: get_payments where clause does query wrong payments including tests (#2844)

* fix: get_payments where clause does query wrong payments (#2841)
This commit is contained in:
dni ⚡ 2024-12-19 10:22:37 +01:00 committed by GitHub
parent f17ff3d12b
commit 3a2cf12052
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 82 additions and 7 deletions

View file

@ -123,15 +123,20 @@ async def get_payments_paginated(
clause.append("wallet_id = :wallet_id") clause.append("wallet_id = :wallet_id")
if complete and pending: if complete and pending:
pass clause.append(
f"(status = '{PaymentState.SUCCESS}' OR status = '{PaymentState.PENDING}')"
)
elif complete: elif complete:
clause.append( clause.append(
f"((amount > 0 AND status = '{PaymentState.SUCCESS}') OR amount < 0)" f"""
(
status = '{PaymentState.SUCCESS}'
OR (amount < 0 AND status = '{PaymentState.PENDING}')
)
"""
) )
elif pending: elif pending:
clause.append(f"status = '{PaymentState.PENDING}'") clause.append(f"status = '{PaymentState.PENDING}'")
else:
pass
if outgoing and incoming: if outgoing and incoming:
pass pass
@ -289,8 +294,14 @@ async def get_payments_history(
values = { values = {
"wallet_id": wallet_id, "wallet_id": wallet_id,
} }
# count outgoing payments if they are still pending
where = [ where = [
f"wallet_id = :wallet_id AND (status = '{PaymentState.SUCCESS}' OR amount < 0)" f"""
wallet_id = :wallet_id AND (
status = '{PaymentState.SUCCESS}'
OR (amount < 0 AND status = '{PaymentState.PENDING}')
)
"""
] ]
transactions: list[dict] = await db.fetchall( transactions: list[dict] = await db.fetchall(
f""" f"""

View file

@ -108,8 +108,6 @@ async def api_payments_paginated(
await update_pending_payments(key_info.wallet.id) await update_pending_payments(key_info.wallet.id)
page = await get_payments_paginated( page = await get_payments_paginated(
wallet_id=key_info.wallet.id, wallet_id=key_info.wallet.id,
pending=True,
complete=True,
filters=filters, filters=filters,
) )
return page return page

View file

@ -0,0 +1,66 @@
import pytest
from lnbits.core.crud import create_wallet, get_payments, update_payment
from lnbits.core.models import PaymentState
from lnbits.core.services import create_user_account, update_wallet_balance
async def update_payments(payments):
payments[0].status = PaymentState.FAILED
await update_payment(payments[0])
payments[1].status = PaymentState.PENDING
await update_payment(payments[1])
payments[2].status = PaymentState.PENDING
await update_payment(payments[2])
@pytest.mark.anyio
async def test_crud_get_payments(app):
user = await create_user_account()
wallet = await create_wallet(user_id=user.id)
for _ in range(11):
await update_wallet_balance(wallet, 10)
wallet.balance_msat += 10 * 1000
await update_wallet_balance(wallet, -10)
wallet.balance_msat += -10 * 1000
payments = await get_payments(wallet_id=wallet.id)
assert len(payments) == 22, "should return 22 successful payments"
payments = await get_payments(wallet_id=wallet.id, incoming=True)
assert len(payments) == 11, "should return 11 successful incoming payments"
await update_payments(payments)
payments = await get_payments(wallet_id=wallet.id, outgoing=True)
assert len(payments) == 11, "should return 11 successful outgoing payments"
await update_payments(payments)
payments = await get_payments(wallet_id=wallet.id, pending=True)
assert len(payments) == 4, "should return 4 pending payments"
# function signature should have Optional[bool] for complete and pending to make
# this distinction possible
payments = await get_payments(wallet_id=wallet.id, pending=False)
assert len(payments) == 22, "should return all payments"
payments = await get_payments(wallet_id=wallet.id, complete=True, pending=True)
assert len(payments) == 20, "should return 4 pending and 16 complete payments"
payments = await get_payments(wallet_id=wallet.id, complete=True, outgoing=True)
assert (
len(payments) == 10
), "should return 8 complete outgoing payments and 2 pending outgoing payments"
payments = await get_payments(wallet_id=wallet.id)
assert len(payments) == 22, "should return all payments"
payments = await get_payments(wallet_id=wallet.id, complete=True)
assert (
len(payments) == 18
), "should return 14 successful payment and 4 pending payments"
# both false should return failed payments
# payments = await get_payments(wallet_id=wallet.id, complete=False, pending=False)
# assert len(payments) == 2, "should return 2 failed payment"