fix: api tests

This commit is contained in:
Vlad Stan
2024-10-17 10:37:46 +02:00
committed by dni ⚡
parent 4361fc7cc2
commit 4aae00c4fa
8 changed files with 99 additions and 107 deletions
+1
View File
@@ -176,6 +176,7 @@ async def get_user(
id=account.id, id=account.id,
email=account.email, email=account.email,
username=account.username, username=account.username,
pubkey=account.pubkey,
extra=account.extra, extra=account.extra,
created_at=account.created_at, created_at=account.created_at,
updated_at=account.updated_at, updated_at=account.updated_at,
+4 -1
View File
@@ -54,6 +54,7 @@ from .crud import (
create_wallet, create_wallet,
get_account, get_account,
get_account_by_email, get_account_by_email,
get_account_by_pubkey,
get_account_by_username, get_account_by_username,
get_payments, get_payments,
get_standalone_payment, get_standalone_payment,
@@ -850,8 +851,10 @@ async def create_user_account(
if account.email and await get_account_by_email(account.email): if account.email and await get_account_by_email(account.email):
raise ValueError("Email already exists.") raise ValueError("Email already exists.")
if account.pubkey and await get_account_by_pubkey(account.pubkey):
raise ValueError("Pubkey already exists.")
if account.id: if account.id:
print("### account", account)
user_uuid4 = UUID(hex=account.id, version=4) user_uuid4 = UUID(hex=account.id, version=4)
assert user_uuid4.hex == account.id, "User ID is not valid UUID4 hex string" assert user_uuid4.hex == account.id, "User ID is not valid UUID4 hex string"
else: else:
+4 -10
View File
@@ -15,7 +15,7 @@ from fastapi import (
from fastapi.exceptions import HTTPException from fastapi.exceptions import HTTPException
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
from lnbits.core.crud import create_account, create_wallet, get_user_by_id from lnbits.core.crud import get_user_by_id
from lnbits.core.models import ( from lnbits.core.models import (
BaseWallet, BaseWallet,
ConversionData, ConversionData,
@@ -41,7 +41,7 @@ from lnbits.utils.exchange_rates import (
from lnbits.wallets import get_funding_source from lnbits.wallets import get_funding_source
from lnbits.wallets.base import StatusResponse from lnbits.wallets.base import StatusResponse
from ..services import perform_lnurlauth from ..services import create_user_account, perform_lnurlauth
api_router = APIRouter(tags=["Core"]) api_router = APIRouter(tags=["Core"])
@@ -90,14 +90,8 @@ async def api_wallets(user: User = Depends(check_user_exists)) -> list[BaseWalle
@api_router.post("/api/v1/account", response_model=Wallet) @api_router.post("/api/v1/account", response_model=Wallet)
async def api_create_account(data: CreateWallet) -> Wallet: async def api_create_account(data: CreateWallet) -> Wallet:
if not settings.new_accounts_allowed: user = await create_user_account(wallet_name=data.name)
raise HTTPException( return user.wallets[0]
status_code=HTTPStatus.FORBIDDEN,
detail="Account creation is disabled.",
)
account = await create_account()
wallet = await create_wallet(user_id=account.id, wallet_name=data.name)
return wallet
@api_router.get("/api/v1/lnurlscan/{code}") @api_router.get("/api/v1/lnurlscan/{code}")
+35 -54
View File
@@ -11,6 +11,7 @@ from fastapi.responses import JSONResponse, RedirectResponse
from fastapi_sso.sso.base import OpenID, SSOBase from fastapi_sso.sso.base import OpenID, SSOBase
from loguru import logger from loguru import logger
from lnbits.core.services import create_user_account
from lnbits.decorators import access_token_payload, check_user_exists from lnbits.decorators import access_token_payload, check_user_exists
from lnbits.helpers import ( from lnbits.helpers import (
create_access_token, create_access_token,
@@ -18,13 +19,11 @@ from lnbits.helpers import (
encrypt_internal_message, encrypt_internal_message,
is_valid_email_address, is_valid_email_address,
is_valid_username, is_valid_username,
urlsafe_short_hash,
) )
from lnbits.settings import AuthMethods, settings from lnbits.settings import AuthMethods, settings
from lnbits.utils.nostr import normalize_public_key, verify_event from lnbits.utils.nostr import normalize_public_key, verify_event
from ..crud import ( from ..crud import (
create_account,
get_account, get_account,
get_account_by_email, get_account_by_email,
get_account_by_pubkey, get_account_by_pubkey,
@@ -84,7 +83,7 @@ async def nostr_login(request: Request) -> JSONResponse:
pubkey=event["pubkey"], pubkey=event["pubkey"],
extra=UserExtra(provider="nostr"), extra=UserExtra(provider="nostr"),
) )
await create_account(account) await create_user_account(account)
return _auth_success_response(account.username or "", account.id, account.email) return _auth_success_response(account.username or "", account.id, account.email)
@@ -182,12 +181,12 @@ async def register(data: CreateUser) -> JSONResponse:
raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, detail="Invalid email.") raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, detail="Invalid email.")
account = Account( account = Account(
id=urlsafe_short_hash(), id=uuid4().hex,
email=data.email, email=data.email,
username=data.username, username=data.username,
) )
account.hash_password(data.password) account.hash_password(data.password)
await create_account(account) await create_user_account(account)
return _auth_success_response(account.username, account.id, account.email) return _auth_success_response(account.username, account.id, account.email)
@@ -225,36 +224,22 @@ async def update_password(
payload: AccessTokenPayload = Depends(access_token_payload), payload: AccessTokenPayload = Depends(access_token_payload),
) -> Optional[User]: ) -> Optional[User]:
if data.user_id != user.id: if data.user_id != user.id:
raise HTTPException( raise HTTPException(HTTPStatus.BAD_REQUEST, "Invalid user ID.")
status_code=HTTPStatus.BAD_REQUEST, detail="Invalid user ID." _validate_auth_timeout(payload.auth_time)
)
if ( if (
data.username data.username
and user.username != data.username and user.username != data.username
and await get_account_by_username(data.username) and await get_account_by_username(data.username)
): ):
raise HTTPException( raise HTTPException(HTTPStatus.BAD_REQUEST, "Username already exists.")
status_code=HTTPStatus.BAD_REQUEST, detail="Username already exists."
)
account = await get_account(user.id) account = await get_account(user.id)
if not account: assert account, "Account not found."
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Account not found."
)
# old accounts do not have a password # old accounts do not have a password
if account.password_hash: if account.password_hash:
if not data.password_old: assert data.password_old, "Missing old password."
raise HTTPException( assert account.verify_password(data.password_old), "Invalid old password."
status_code=HTTPStatus.BAD_REQUEST, detail="Missing old password."
)
if not account.verify_password(data.password_old):
raise HTTPException(
status_code=HTTPStatus.BAD_REQUEST, detail="Invalid credentials."
)
_validate_auth_timeout(payload.auth_time)
account.username = data.username account.username = data.username
account.hash_password(data.password) account.hash_password(data.password)
@@ -275,9 +260,12 @@ async def reset_password(data: ResetUserPassword) -> JSONResponse:
assert data.password == data.password_repeat, "Passwords do not match." assert data.password == data.password_repeat, "Passwords do not match."
assert data.reset_key[:10].startswith("reset_key_"), "This is not a reset key." assert data.reset_key[:10].startswith("reset_key_"), "This is not a reset key."
reset_data_json = decrypt_internal_message( try:
base64.b64decode(data.reset_key[10:]).decode() reset_key = base64.b64decode(data.reset_key[10:]).decode()
) reset_data_json = decrypt_internal_message(reset_key)
except Exception as exc:
raise ValueError("Invalid reset key.") from exc
assert reset_data_json, "Cannot process reset key." assert reset_data_json, "Cannot process reset key."
action, user_id, request_time = json.loads(reset_data_json) action, user_id, request_time = json.loads(reset_data_json)
@@ -384,12 +372,10 @@ async def _handle_sso_login(userinfo: OpenID, verified_user_id: Optional[str] =
account.extra.email_verified = True account.extra.email_verified = True
await update_account(account) await update_account(account)
else: else:
if not settings.new_accounts_allowed:
raise HTTPException(HTTPStatus.BAD_REQUEST, "Account creation is disabled.")
account = Account( account = Account(
id=uuid4().hex, email=email, extra=UserExtra(email_verified=True) id=uuid4().hex, email=email, extra=UserExtra(email_verified=True)
) )
await create_account(account) await create_user_account(account)
return _auth_redirect_response(redirect_path, email) return _auth_redirect_response(redirect_path, email)
@@ -476,40 +462,35 @@ def _nostr_nip98_event(request: Request) -> dict:
event = json.loads(event_json) event = json.loads(event_json)
except Exception as exc: except Exception as exc:
logger.warning(exc) logger.warning(exc)
if not event: assert event, "Nostr login event cannot be parsed."
raise HTTPException(
HTTPStatus.BAD_REQUEST, "Nostr login event cannot be parsed."
)
if not verify_event(event): if not verify_event(event):
raise HTTPException(HTTPStatus.BAD_REQUEST, "Nostr login event is not valid.") raise HTTPException(HTTPStatus.BAD_REQUEST, "Nostr login event is not valid.")
if event["kind"] != 27_235: assert event["kind"] == 27_235, "Invalid event kind."
raise HTTPException(HTTPStatus.BAD_REQUEST, "Invalid event kind.")
auth_threshold = settings.auth_credetials_update_threshold auth_threshold = settings.auth_credetials_update_threshold
if abs(time() - event["created_at"]) > auth_threshold: assert (
raise HTTPException( abs(time() - event["created_at"]) < auth_threshold
HTTPStatus.BAD_REQUEST, ), f"More than {auth_threshold} seconds have passed since the event was signed."
f"{auth_threshold} seconds have passed since the event was signed.",
)
method: Optional[str] = next((v for k, v in event["tags"] if k == "method"), None) method: Optional[str] = next((v for k, v in event["tags"] if k == "method"), None)
if not method: assert method, "Tag 'method' is missing."
raise HTTPException(HTTPStatus.BAD_REQUEST, "Tag 'method' is missing.") assert method.upper() == "POST", "Invalid value for tag 'method'."
if method.upper() != "POST":
raise HTTPException(HTTPStatus.BAD_REQUEST, "Invalid value for tag 'method'.")
url = next((v for k, v in event["tags"] if k == "u"), None) url = next((v for k, v in event["tags"] if k == "u"), None)
if not url:
raise HTTPException(HTTPStatus.BAD_REQUEST, "Tag 'u' for URL is missing.") assert url, "Tag 'u' for URL is missing."
accepted_urls = [f"{u}/nostr" for u in settings.nostr_absolute_request_urls] accepted_urls = [f"{u}/nostr" for u in settings.nostr_absolute_request_urls]
if url not in accepted_urls: assert url in accepted_urls, f"Invalid value for tag 'u': '{url}'."
raise HTTPException(HTTPStatus.BAD_REQUEST, "Invalid value for tag 'u'.")
return event return event
def _validate_auth_timeout(auth_time: Optional[int] = None): def _validate_auth_timeout(auth_time: Optional[int] = 0):
if int(time()) - int(auth_time or 0) > settings.auth_credetials_update_threshold: if abs(time() - (auth_time or 0)) > settings.auth_credetials_update_threshold:
raise HTTPException( raise HTTPException(
HTTPStatus.BAD_REQUEST, HTTPStatus.BAD_REQUEST,
"You can only update your credentials in the first" "You can only update your credentials in the first"
f" {settings.auth_credetials_update_threshold} seconds after login." f" {settings.auth_credetials_update_threshold} seconds."
" Please login again!", " Please login again or ask a new reset key!",
) )
+2 -3
View File
@@ -14,7 +14,7 @@ from pydantic.types import UUID4
from lnbits.core.extensions.models import Extension, ExtensionMeta, InstallableExtension from lnbits.core.extensions.models import Extension, ExtensionMeta, InstallableExtension
from lnbits.core.helpers import to_valid_user_id from lnbits.core.helpers import to_valid_user_id
from lnbits.core.models import User from lnbits.core.models import User
from lnbits.core.services import create_invoice from lnbits.core.services import create_invoice, create_user_account
from lnbits.decorators import check_admin, check_user_exists from lnbits.decorators import check_admin, check_user_exists
from lnbits.helpers import template_renderer from lnbits.helpers import template_renderer
from lnbits.settings import settings from lnbits.settings import settings
@@ -22,7 +22,6 @@ from lnbits.wallets import get_funding_source
from ...utils.exchange_rates import allowed_currencies, currencies from ...utils.exchange_rates import allowed_currencies, currencies
from ..crud import ( from ..crud import (
create_account,
create_wallet, create_wallet,
get_dbversions, get_dbversions,
get_installed_extensions, get_installed_extensions,
@@ -424,7 +423,7 @@ async def lnurlwallet(request: Request):
status_code=HTTPStatus.BAD_REQUEST, status_code=HTTPStatus.BAD_REQUEST,
detail="Invalid lnurl. Expected maxWithdrawable", detail="Invalid lnurl. Expected maxWithdrawable",
) )
account = await create_account() account = await create_user_account()
wallet = await create_wallet(user_id=account.id) wallet = await create_wallet(user_id=account.id)
_, payment_request = await create_invoice( _, payment_request = await create_invoice(
wallet_id=wallet.id, wallet_id=wallet.id,
+8
View File
@@ -76,6 +76,14 @@ def register_exception_handlers(app: FastAPI):
content={"detail": str(exc)}, content={"detail": str(exc)},
) )
@app.exception_handler(ValueError)
async def value_error_handler(request: Request, exc: ValueError):
logger.warning(f"ValueError: {exc!s}")
return render_html_error(request, exc) or JSONResponse(
status_code=HTTPStatus.BAD_REQUEST,
content={"detail": str(exc)},
)
@app.exception_handler(RequestValidationError) @app.exception_handler(RequestValidationError)
async def validation_exception_handler( async def validation_exception_handler(
request: Request, exc: RequestValidationError request: Request, exc: RequestValidationError
+28 -26
View File
@@ -255,7 +255,8 @@ async def test_register_email_twice(http_client: AsyncClient):
"email": f"u21.{tiny_id}@lnbits.com", "email": f"u21.{tiny_id}@lnbits.com",
}, },
) )
assert response.status_code == 403, "Not allowed."
assert response.status_code == 400, "Not allowed."
assert response.json().get("detail") == "Email already exists." assert response.json().get("detail") == "Email already exists."
@@ -285,7 +286,7 @@ async def test_register_username_twice(http_client: AsyncClient):
"email": f"u21.{tiny_id_2}@lnbits.com", "email": f"u21.{tiny_id_2}@lnbits.com",
}, },
) )
assert response.status_code == 403, "Not allowed." assert response.status_code == 400, "Not allowed."
assert response.json().get("detail") == "Username already exists." assert response.json().get("detail") == "Username already exists."
@@ -414,8 +415,8 @@ async def test_alan_change_password_old_nok(user_alan: User, http_client: AsyncC
}, },
) )
assert response.status_code == 403, "Old password bad." assert response.status_code == 400, "Old password bad."
assert response.json().get("detail") == "Invalid credentials." assert response.json().get("detail") == "Invalid old password."
@pytest.mark.asyncio @pytest.mark.asyncio
@@ -469,7 +470,7 @@ async def test_alan_change_password_auth_threshold_expired(
}, },
) )
assert response.status_code == 403, "Treshold expired." assert response.status_code == 400
assert ( assert (
response.json().get("detail") == "You can only update your credentials" response.json().get("detail") == "You can only update your credentials"
" in the first 1 seconds." " in the first 1 seconds."
@@ -507,6 +508,7 @@ async def test_register_nostr_ok(http_client: AsyncClient):
response = await http_client.get( response = await http_client.get(
"/api/v1/auth", headers={"Authorization": f"Bearer {access_token}"} "/api/v1/auth", headers={"Authorization": f"Bearer {access_token}"}
) )
user = User(**response.json()) user = User(**response.json())
assert user.username is None, "No username." assert user.username is None, "No username."
assert user.email is None, "No email." assert user.email is None, "No email."
@@ -547,13 +549,13 @@ async def test_register_nostr_bad_header(http_client: AsyncClient):
) )
assert response.status_code == 401, "Non nostr header." assert response.status_code == 401, "Non nostr header."
assert response.json().get("detail") == "Authorization header is not nostr." assert response.json().get("detail") == "Invalid Authorization scheme."
response = await http_client.post( response = await http_client.post(
"/api/v1/auth/nostr", "/api/v1/auth/nostr",
headers={"Authorization": "nostr xyz"}, headers={"Authorization": "nostr xyz"},
) )
assert response.status_code == 401, "Nostr not base64." assert response.status_code == 400, "Nostr not base64."
assert response.json().get("detail") == "Nostr login event cannot be parsed." assert response.json().get("detail") == "Nostr login event cannot be parsed."
@@ -565,7 +567,7 @@ async def test_register_nostr_bad_event(http_client: AsyncClient):
"/api/v1/auth/nostr", "/api/v1/auth/nostr",
headers={"Authorization": f"nostr {base64_event}"}, headers={"Authorization": f"nostr {base64_event}"},
) )
assert response.status_code == 401, "Nostr event expired." assert response.status_code == 400, "Nostr event expired."
assert ( assert (
response.json().get("detail") response.json().get("detail")
== f"More than {settings.auth_credetials_update_threshold}" == f"More than {settings.auth_credetials_update_threshold}"
@@ -581,7 +583,7 @@ async def test_register_nostr_bad_event(http_client: AsyncClient):
"/api/v1/auth/nostr", "/api/v1/auth/nostr",
headers={"Authorization": f"nostr {base64_event}"}, headers={"Authorization": f"nostr {base64_event}"},
) )
assert response.status_code == 401, "Nostr event signature invalid." assert response.status_code == 400, "Nostr event signature invalid."
assert response.json().get("detail") == "Nostr login event is not valid." assert response.json().get("detail") == "Nostr login event is not valid."
@@ -598,7 +600,7 @@ async def test_register_nostr_bad_event_kind(http_client: AsyncClient):
"/api/v1/auth/nostr", "/api/v1/auth/nostr",
headers={"Authorization": f"nostr {base64_event_bad_kind}"}, headers={"Authorization": f"nostr {base64_event_bad_kind}"},
) )
assert response.status_code == 401, "Nostr event kind invalid." assert response.status_code == 400, "Nostr event kind invalid."
assert response.json().get("detail") == "Invalid event kind." assert response.json().get("detail") == "Invalid event kind."
@@ -617,7 +619,7 @@ async def test_register_nostr_bad_event_tag_u(http_client: AsyncClient):
"/api/v1/auth/nostr", "/api/v1/auth/nostr",
headers={"Authorization": f"nostr {base64_event_tag_kind}"}, headers={"Authorization": f"nostr {base64_event_tag_kind}"},
) )
assert response.status_code == 401, "Nostr event tag missing." assert response.status_code == 400, "Nostr event tag missing."
assert response.json().get("detail") == "Tag 'method' is missing." assert response.json().get("detail") == "Tag 'method' is missing."
event_bad_kind["tags"] = [["u", "http://localhost:5000/nostr"], ["method", "XYZ"]] event_bad_kind["tags"] = [["u", "http://localhost:5000/nostr"], ["method", "XYZ"]]
@@ -630,8 +632,8 @@ async def test_register_nostr_bad_event_tag_u(http_client: AsyncClient):
"/api/v1/auth/nostr", "/api/v1/auth/nostr",
headers={"Authorization": f"nostr {base64_event_tag_kind}"}, headers={"Authorization": f"nostr {base64_event_tag_kind}"},
) )
assert response.status_code == 401, "Nostr event tag invalid." assert response.status_code == 400, "Nostr event tag invalid."
assert response.json().get("detail") == "Incorrect value for tag 'method'." assert response.json().get("detail") == "Invalid value for tag 'method'."
@pytest.mark.asyncio @pytest.mark.asyncio
@@ -649,7 +651,7 @@ async def test_register_nostr_bad_event_tag_menthod(http_client: AsyncClient):
"/api/v1/auth/nostr", "/api/v1/auth/nostr",
headers={"Authorization": f"nostr {base64_event}"}, headers={"Authorization": f"nostr {base64_event}"},
) )
assert response.status_code == 401, "Nostr event tag missing." assert response.status_code == 400, "Nostr event tag missing."
assert response.json().get("detail") == "Tag 'u' for URL is missing." assert response.json().get("detail") == "Tag 'u' for URL is missing."
event_bad_kind["tags"] = [["u", "http://demo.lnbits.com/nostr"], ["method", "POST"]] event_bad_kind["tags"] = [["u", "http://demo.lnbits.com/nostr"], ["method", "POST"]]
@@ -662,15 +664,15 @@ async def test_register_nostr_bad_event_tag_menthod(http_client: AsyncClient):
"/api/v1/auth/nostr", "/api/v1/auth/nostr",
headers={"Authorization": f"nostr {base64_event}"}, headers={"Authorization": f"nostr {base64_event}"},
) )
assert response.status_code == 401, "Nostr event tag invalid." assert response.status_code == 400, "Nostr event tag invalid."
assert ( assert (
response.json().get("detail") == "Incorrect value for tag 'u':" response.json().get("detail") == "Invalid value for tag 'u':"
" 'http://demo.lnbits.com/nostr'." " 'http://demo.lnbits.com/nostr'."
) )
################################ CHANGE PUBLIC KEY ################################ ################################ CHANGE PUBLIC KEY ################################
async def test_change_pubkey_npub_ok(http_client: AsyncClient, user_alan: User): async def test_change_pubkey_npub_ok(http_client: AsyncClient):
tiny_id = shortuuid.uuid()[:8] tiny_id = shortuuid.uuid()[:8]
response = await http_client.post( response = await http_client.post(
"/api/v1/auth/register", "/api/v1/auth/register",
@@ -790,7 +792,7 @@ async def test_change_pubkey_ok(http_client: AsyncClient, user_alan: User):
}, },
) )
assert response.status_code == 403, "Pubkey already used." assert response.status_code == 400, "Pubkey already used."
assert response.json().get("detail") == "Public key already in use." assert response.json().get("detail") == "Public key already in use."
@@ -852,11 +854,11 @@ async def test_alan_change_pubkey_auth_threshold_expired(
}, },
) )
assert response.status_code == 403, "Treshold expired." assert response.status_code == 400, "Treshold expired."
assert ( assert (
response.json().get("detail") == "You can only update your credentials" response.json().get("detail") == "You can only update your credentials"
" in the first 1 seconds after login." " in the first 1 seconds."
" Please login again!" " Please login again or ask a new reset key!"
) )
@@ -929,7 +931,7 @@ async def test_request_reset_key_user_not_found(http_client: AsyncClient):
}, },
) )
assert response.status_code == 403, "User does not exist." assert response.status_code == 404, "User does not exist."
assert response.json().get("detail") == "User not found." assert response.json().get("detail") == "User not found."
@@ -975,7 +977,7 @@ async def test_reset_username_passwords_do_not_matcj(
}, },
) )
assert response.status_code == 403, "Passwords do not match." assert response.status_code == 400, "Passwords do not match."
assert response.json().get("detail") == "Passwords do not match." assert response.json().get("detail") == "Passwords do not match."
@@ -990,8 +992,8 @@ async def test_reset_username_password_bad_key(http_client: AsyncClient):
"password_repeat": "secret0000", "password_repeat": "secret0000",
}, },
) )
assert response.status_code == 500, "Bad reset key." assert response.status_code == 400, "Bad reset key."
assert response.json().get("detail") == "Cannot reset user password." assert response.json().get("detail") == "Invalid reset key."
@pytest.mark.asyncio @pytest.mark.asyncio
@@ -1013,7 +1015,7 @@ async def test_reset_password_auth_threshold_expired(
}, },
) )
assert response.status_code == 403, "Treshold expired." assert response.status_code == 400, "Treshold expired."
assert ( assert (
response.json().get("detail") == "You can only update your credentials" response.json().get("detail") == "You can only update your credentials"
" in the first 1 seconds." " in the first 1 seconds."
+17 -13
View File
@@ -18,15 +18,15 @@ from httpx import ASGITransport, AsyncClient
from lnbits.app import create_app from lnbits.app import create_app
from lnbits.core.crud import ( from lnbits.core.crud import (
create_account,
create_wallet, create_wallet,
delete_account,
get_account, get_account,
get_account_by_username, get_account_by_username,
get_user, get_user,
update_payment_status, update_payment_status,
) )
from lnbits.core.models import Account, CreateInvoice, PaymentState from lnbits.core.models import Account, CreateInvoice, PaymentState
from lnbits.core.services import update_wallet_balance from lnbits.core.services import create_user_account, update_wallet_balance
from lnbits.core.views.payment_api import api_payments_create_invoice from lnbits.core.views.payment_api import api_payments_create_invoice
from lnbits.db import DB_TYPE, SQLITE, Database from lnbits.db import DB_TYPE, SQLITE, Database
from lnbits.settings import AuthMethods, settings from lnbits.settings import AuthMethods, settings
@@ -47,6 +47,7 @@ def run_before_and_after_tests():
##### BEFORE TEST RUN ##### ##### BEFORE TEST RUN #####
settings.lnbits_allow_new_accounts = True settings.lnbits_allow_new_accounts = True
settings.lnbits_allowed_users = []
settings.auth_allowed_methods = AuthMethods.all() settings.auth_allowed_methods = AuthMethods.all()
settings.auth_credetials_update_threshold = 120 settings.auth_credetials_update_threshold = 120
settings.lnbits_reserve_fee_percent = 1 settings.lnbits_reserve_fee_percent = 1
@@ -105,20 +106,23 @@ async def db():
@pytest_asyncio.fixture(scope="session") @pytest_asyncio.fixture(scope="session")
async def user_alan(): async def user_alan():
account = await get_account_by_username("alan") account = await get_account_by_username("alan")
if not account: if account:
account = Account( await delete_account(account.id)
id=uuid4().hex,
email="alan@lnbits.com", account = Account(
username="alan", id=uuid4().hex,
) email="alan@lnbits.com",
account.hash_password("secret1234") username="alan",
account = await create_account(account) )
yield account account.hash_password("secret1234")
user = await create_user_account(account)
yield user
@pytest_asyncio.fixture(scope="session") @pytest_asyncio.fixture(scope="session")
async def from_user(): async def from_user():
user = await create_account() user = await create_user_account()
yield user yield user
@@ -143,7 +147,7 @@ async def from_wallet_ws(from_wallet, test_client):
@pytest_asyncio.fixture(scope="session") @pytest_asyncio.fixture(scope="session")
async def to_user(): async def to_user():
user = await create_account() user = await create_user_account()
yield user yield user