lnbits-legend/tests/wallets/helpers.py

139 lines
4.5 KiB
Python
Raw Normal View History

import functools
import importlib
import json
import operator
from typing import Dict, List
import pytest
from lnbits.core.models import BaseWallet
from tests.wallets.fixtures.models import FundingSourceConfig, WalletTest
wallets_module = importlib.import_module("lnbits.wallets")
def wallet_fixtures_from_json(path) -> List["WalletTest"]:
with open(path) as f:
data = json.load(f)
funding_sources = [
FundingSourceConfig(name=fs_name, **data["funding_sources"][fs_name])
for fs_name in data["funding_sources"]
]
tests: Dict[str, List[WalletTest]] = {}
for fn_name in data["functions"]:
fn = data["functions"][fn_name]
fn_tests = _tests_for_function(funding_sources, fn_name, fn)
_merge_dict_of_lists(tests, fn_tests)
all_tests: list["WalletTest"] = functools.reduce(
operator.iadd, [tests[fs_name] for fs_name in tests], []
)
return all_tests
def _tests_for_function(
funding_sources: List[FundingSourceConfig], fn_name: str, fn
) -> Dict[str, List[WalletTest]]:
tests: Dict[str, List[WalletTest]] = {}
for test in fn["tests"]:
"""create an unit test for each funding source"""
fs_tests = _tests_for_funding_source(funding_sources, fn_name, fn, test)
_merge_dict_of_lists(tests, fs_tests)
return tests
def _tests_for_funding_source(
funding_sources: List[FundingSourceConfig], fn_name: str, fn, test
) -> Dict[str, List[WalletTest]]:
tests: Dict[str, List[WalletTest]] = {fs.name: [] for fs in funding_sources}
for fs in funding_sources:
tests[fs.name] += WalletTest.tests_for_funding_source(fs, fn_name, fn, test)
return tests
def build_test_id(test: WalletTest):
2024-04-19 14:21:21 +03:00
return f"{test.funding_source.name}.{test.function}({test.description})"
def load_funding_source(funding_source: FundingSourceConfig) -> BaseWallet:
custom_settings = funding_source.settings
original_settings = {}
settings = wallets_module.settings
for s in custom_settings:
original_settings[s] = getattr(settings, s)
setattr(settings, s, custom_settings[s])
fs_instance: BaseWallet = getattr(wallets_module, funding_source.wallet_class)()
# rollback settings (global variable)
for s in original_settings:
setattr(settings, s, original_settings[s])
return fs_instance
async def check_assertions(wallet, _test_data: WalletTest):
test_data = _test_data.dict()
tested_func = _test_data.function
call_params = _test_data.call_params
if "expect" in test_data:
2024-04-19 14:21:21 +03:00
await _assert_data(
wallet,
tested_func,
call_params,
_test_data.expect,
_test_data.description,
)
# if len(_test_data.mocks) == 0:
# # all calls should fail after this method is called
# await wallet.cleanup()
# # same behaviour expected is server canot be reached
# # or if the connection was closed
# await _assert_data(wallet, tested_func, call_params, _test_data.expect)
elif "expect_error" in test_data:
await _assert_error(wallet, tested_func, call_params, _test_data.expect_error)
else:
raise AssertionError("Expected outcome not specified")
2024-04-19 14:21:21 +03:00
async def _assert_data(wallet, tested_func, call_params, expect, description):
resp = await getattr(wallet, tested_func)(**call_params)
2024-04-19 14:21:21 +03:00
fn_prefix = "__eval__:"
for key in expect:
expected = expect[key]
2024-04-19 14:21:21 +03:00
if key.startswith(fn_prefix):
key = key[len(fn_prefix) :]
received = getattr(resp, key)
expected = expected.format(**{key: received, "description": description})
_assert = eval(expected)
else:
received = getattr(resp, key)
_assert = getattr(resp, key) == expect[key]
assert _assert, (
f""" Field "{key}"."""
f""" Received: "{received}"."""
f""" Expected: "{expected}"."""
)
async def _assert_error(wallet, tested_func, call_params, expect_error):
error_module = importlib.import_module(expect_error["module"])
error_class = getattr(error_module, expect_error["class"])
with pytest.raises(error_class) as e_info:
await getattr(wallet, tested_func)(**call_params)
assert e_info.match(expect_error["message"])
def _merge_dict_of_lists(v1: Dict[str, List], v2: Dict[str, List]):
"""Merge v2 into v1"""
for k in v2:
v1[k] = v2[k] if k not in v1 else v1[k] + v2[k]