191 lines
5.9 KiB
Python
191 lines
5.9 KiB
Python
from uuid import uuid4
|
|
|
|
import pytest
|
|
from httpx import AsyncClient
|
|
|
|
from lnbits.core.crud.wallets import create_wallet, get_wallet
|
|
from lnbits.core.models.users import Account
|
|
from lnbits.core.services.users import create_user_account
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_wallet_api_share_invite_reject_accept_and_delete(
|
|
http_client: AsyncClient,
|
|
):
|
|
owner = await create_user_account(
|
|
Account(
|
|
id=uuid4().hex,
|
|
username=f"owner_{uuid4().hex[:8]}",
|
|
email=f"owner_{uuid4().hex[:8]}@lnbits.com",
|
|
)
|
|
)
|
|
invited = await create_user_account(
|
|
Account(
|
|
id=uuid4().hex,
|
|
username=f"invited_{uuid4().hex[:8]}",
|
|
email=f"invited_{uuid4().hex[:8]}@lnbits.com",
|
|
)
|
|
)
|
|
source_wallet = owner.wallets[0]
|
|
owner_headers = _admin_headers(source_wallet.adminkey)
|
|
|
|
invite = await http_client.put(
|
|
"/api/v1/wallet/share/invite",
|
|
headers=owner_headers,
|
|
json={
|
|
"username": invited.username,
|
|
"permissions": ["view-payments"],
|
|
"status": "invite_sent",
|
|
},
|
|
)
|
|
assert invite.status_code == 200
|
|
share_request = invite.json()
|
|
assert share_request["request_id"]
|
|
|
|
reject = await http_client.delete(
|
|
f"/api/v1/wallet/share/invite/{share_request['request_id']}?usr={invited.id}"
|
|
)
|
|
assert reject.status_code == 200
|
|
assert reject.json()["success"] is True
|
|
|
|
removed_share = await http_client.delete(
|
|
f"/api/v1/wallet/share/{share_request['request_id']}",
|
|
headers=owner_headers,
|
|
)
|
|
assert removed_share.status_code == 200
|
|
assert removed_share.json()["success"] is True
|
|
|
|
invite = await http_client.put(
|
|
"/api/v1/wallet/share/invite",
|
|
headers=owner_headers,
|
|
json={
|
|
"username": invited.username,
|
|
"permissions": ["view-payments", "receive-payments"],
|
|
"status": "invite_sent",
|
|
},
|
|
)
|
|
assert invite.status_code == 200
|
|
share_request = invite.json()
|
|
|
|
create_shared = await http_client.post(
|
|
f"/api/v1/wallet?usr={invited.id}",
|
|
json={
|
|
"name": "shared",
|
|
"wallet_type": "lightning-shared",
|
|
"shared_wallet_id": source_wallet.id,
|
|
},
|
|
)
|
|
assert create_shared.status_code == 200
|
|
mirror_wallet = create_shared.json()
|
|
assert mirror_wallet["shared_wallet_id"] == source_wallet.id
|
|
|
|
approve = await http_client.put(
|
|
"/api/v1/wallet/share",
|
|
headers=owner_headers,
|
|
json={
|
|
"username": invited.username,
|
|
"shared_with_wallet_id": mirror_wallet["id"],
|
|
"permissions": ["view-payments", "receive-payments"],
|
|
"status": "approved",
|
|
},
|
|
)
|
|
assert approve.status_code == 200
|
|
assert approve.json()["status"] == "approved"
|
|
|
|
delete_share = await http_client.delete(
|
|
f"/api/v1/wallet/share/{share_request['request_id']}",
|
|
headers=owner_headers,
|
|
)
|
|
assert delete_share.status_code == 200
|
|
assert delete_share.json()["success"] is True
|
|
assert await get_wallet(mirror_wallet["id"]) is None
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_wallet_api_paginated_update_reset_and_store_paylinks(
|
|
http_client: AsyncClient,
|
|
):
|
|
user = await create_user_account(
|
|
Account(
|
|
id=uuid4().hex,
|
|
username=f"user_{uuid4().hex[:8]}",
|
|
email=f"user_{uuid4().hex[:8]}@lnbits.com",
|
|
)
|
|
)
|
|
extra_wallet = await create_wallet(user_id=user.id, wallet_name="second")
|
|
first_wallet = user.wallets[0]
|
|
|
|
page = await http_client.get(f"/api/v1/wallet/paginated?usr={user.id}&limit=10")
|
|
assert page.status_code == 200
|
|
assert page.json()["total"] >= 2
|
|
|
|
renamed = await http_client.put(
|
|
"/api/v1/wallet/renamed-wallet",
|
|
headers=_admin_headers(first_wallet.adminkey),
|
|
)
|
|
assert renamed.status_code == 200
|
|
assert renamed.json()["name"] == "renamed-wallet"
|
|
|
|
original_admin_key = extra_wallet.adminkey
|
|
reset = await http_client.put(
|
|
f"/api/v1/wallet/reset/{extra_wallet.id}?usr={user.id}"
|
|
)
|
|
assert reset.status_code == 200
|
|
assert reset.json()["adminkey"] != original_admin_key
|
|
|
|
stored = await http_client.put(
|
|
f"/api/v1/wallet/stored_paylinks/{extra_wallet.id}",
|
|
headers=_admin_headers(reset.json()["adminkey"]),
|
|
json={
|
|
"links": [
|
|
{
|
|
"lnurl": "alice@example.com",
|
|
"label": "Alice",
|
|
}
|
|
]
|
|
},
|
|
)
|
|
assert stored.status_code == 200
|
|
assert stored.json()[0]["lnurl"] == "alice@example.com"
|
|
|
|
forbidden = await http_client.put(
|
|
f"/api/v1/wallet/stored_paylinks/{extra_wallet.id}",
|
|
headers=_admin_headers(first_wallet.adminkey),
|
|
json={"links": []},
|
|
)
|
|
assert forbidden.status_code == 403
|
|
|
|
updated = await http_client.patch(
|
|
"/api/v1/wallet",
|
|
headers=_admin_headers(first_wallet.adminkey),
|
|
json={"icon": "bolt", "color": "amber", "pinned": True},
|
|
)
|
|
assert updated.status_code == 200
|
|
assert updated.json()["extra"]["icon"] == "bolt"
|
|
assert updated.json()["extra"]["color"] == "amber"
|
|
assert updated.json()["extra"]["pinned"] is True
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_wallet_api_shared_wallet_requires_source_id(http_client: AsyncClient):
|
|
user = await create_user_account(
|
|
Account(
|
|
id=uuid4().hex,
|
|
username=f"user_{uuid4().hex[:8]}",
|
|
email=f"user_{uuid4().hex[:8]}@lnbits.com",
|
|
)
|
|
)
|
|
|
|
response = await http_client.post(
|
|
f"/api/v1/wallet?usr={user.id}",
|
|
json={"wallet_type": "lightning-shared"},
|
|
)
|
|
assert response.status_code == 400
|
|
assert (
|
|
response.json()["detail"] == "Shared wallet ID is required for shared wallets."
|
|
)
|
|
|
|
|
|
def _admin_headers(adminkey: str) -> dict[str, str]:
|
|
return {"X-Api-Key": adminkey, "Content-type": "application/json"}
|