156 lines
5.2 KiB
Python
156 lines
5.2 KiB
Python
import pytest
|
|
from pydantic import ValidationError
|
|
from pytest_mock.plugin import MockerFixture
|
|
|
|
from lnbits.core.crud import (
|
|
create_admin_settings,
|
|
delete_admin_settings,
|
|
get_super_settings,
|
|
)
|
|
from lnbits.core.crud.settings import get_settings_field
|
|
from lnbits.core.services.settings import (
|
|
check_webpush_settings,
|
|
dict_to_settings,
|
|
update_cached_settings,
|
|
)
|
|
from lnbits.settings import Settings
|
|
|
|
|
|
class FakePublicKey:
|
|
def public_bytes(self, *_args, **_kwargs):
|
|
return b"public-bytes"
|
|
|
|
|
|
class FakeVapid:
|
|
def __init__(self, has_public_key: bool = True):
|
|
self.public_key = FakePublicKey() if has_public_key else None
|
|
|
|
def generate_keys(self):
|
|
return None
|
|
|
|
def private_pem(self):
|
|
return b"private-key"
|
|
|
|
|
|
def test_dict_to_settings_parses_known_values():
|
|
parsed = dict_to_settings(
|
|
{
|
|
"lnbits_site_title": "Test Title",
|
|
"lnbits_service_fee": 5,
|
|
"lnbits_default_burger_menu_background": False,
|
|
"ignored_field": "ignored",
|
|
}
|
|
)
|
|
|
|
assert parsed.lnbits_site_title == "Test Title"
|
|
assert parsed.lnbits_service_fee == 5
|
|
assert parsed.lnbits_default_burger_menu_background is False
|
|
assert not hasattr(parsed, "ignored_field")
|
|
|
|
|
|
def test_dict_to_settings_validates_invalid_values():
|
|
with pytest.raises(ValidationError):
|
|
dict_to_settings({"lnbits_service_fee": "not-a-number"})
|
|
|
|
|
|
def test_update_cached_settings_updates_runtime_values(settings: Settings):
|
|
original_title = settings.lnbits_site_title
|
|
original_host = settings.host
|
|
original_super_user = settings.super_user
|
|
try:
|
|
update_cached_settings(
|
|
{
|
|
"lnbits_site_title": "Updated",
|
|
"host": "forbidden-host",
|
|
"super_user": "super-user-id",
|
|
"missing_field": "ignored",
|
|
}
|
|
)
|
|
|
|
assert settings.lnbits_site_title == "Updated"
|
|
assert settings.host == original_host
|
|
assert settings.super_user == "super-user-id"
|
|
finally:
|
|
settings.lnbits_site_title = original_title
|
|
settings.host = original_host
|
|
settings.super_user = original_super_user
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_check_webpush_settings_generates_and_persists_keys(
|
|
settings: Settings, mocker: MockerFixture
|
|
):
|
|
previous_settings = await get_super_settings()
|
|
previous_private = settings.lnbits_webpush_privkey
|
|
previous_public = settings.lnbits_webpush_pubkey
|
|
previous_admin_ui = settings.lnbits_admin_ui
|
|
await delete_admin_settings()
|
|
|
|
settings.lnbits_webpush_privkey = ""
|
|
settings.lnbits_webpush_pubkey = None
|
|
settings.lnbits_admin_ui = True
|
|
mocker.patch("lnbits.core.services.settings.Vapid", return_value=FakeVapid())
|
|
mocker.patch(
|
|
"lnbits.core.services.settings.b64urlencode", return_value="public-key"
|
|
)
|
|
try:
|
|
await check_webpush_settings()
|
|
|
|
stored_private = await get_settings_field("lnbits_webpush_privkey")
|
|
stored_public = await get_settings_field("lnbits_webpush_pubkey")
|
|
|
|
assert settings.lnbits_webpush_privkey == "private-key"
|
|
assert settings.lnbits_webpush_pubkey == "public-key"
|
|
assert stored_private is not None
|
|
assert stored_private.value == "private-key"
|
|
assert stored_public is not None
|
|
assert stored_public.value == "public-key"
|
|
finally:
|
|
await delete_admin_settings()
|
|
if previous_settings:
|
|
await create_admin_settings(
|
|
previous_settings.super_user,
|
|
previous_settings.dict(exclude={"super_user"}),
|
|
)
|
|
update_cached_settings(previous_settings.dict())
|
|
settings.lnbits_webpush_privkey = previous_private
|
|
settings.lnbits_webpush_pubkey = previous_public
|
|
settings.lnbits_admin_ui = previous_admin_ui
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_check_webpush_settings_requires_public_key(
|
|
settings: Settings, mocker: MockerFixture
|
|
):
|
|
mocker.patch.object(settings, "lnbits_webpush_privkey", "")
|
|
mocker.patch.object(settings, "lnbits_admin_ui", False)
|
|
mocker.patch(
|
|
"lnbits.core.services.settings.Vapid",
|
|
return_value=FakeVapid(has_public_key=False),
|
|
)
|
|
|
|
with pytest.raises(ValueError, match="VAPID public key does not exist"):
|
|
await check_webpush_settings()
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_check_webpush_settings_skips_generation_when_keys_exist(
|
|
settings: Settings, mocker: MockerFixture
|
|
):
|
|
previous_private = settings.lnbits_webpush_privkey
|
|
previous_public = settings.lnbits_webpush_pubkey
|
|
previous_private_field = await get_settings_field("lnbits_webpush_privkey")
|
|
previous_public_field = await get_settings_field("lnbits_webpush_pubkey")
|
|
settings.lnbits_webpush_privkey = "existing-private-key"
|
|
settings.lnbits_webpush_pubkey = "existing-public-key"
|
|
vapid = mocker.patch("lnbits.core.services.settings.Vapid")
|
|
try:
|
|
await check_webpush_settings()
|
|
finally:
|
|
settings.lnbits_webpush_privkey = previous_private
|
|
settings.lnbits_webpush_pubkey = previous_public
|
|
|
|
assert await get_settings_field("lnbits_webpush_privkey") == previous_private_field
|
|
assert await get_settings_field("lnbits_webpush_pubkey") == previous_public_field
|
|
vapid.assert_not_called()
|