diff --git a/.github/actions/prepare/action.yml b/.github/actions/prepare/action.yml index f43d5d9a..61547bf2 100644 --- a/.github/actions/prepare/action.yml +++ b/.github/actions/prepare/action.yml @@ -47,6 +47,7 @@ runs: - name: Install the project dependencies shell: bash run: | + poetry env use python${{ inputs.python-version }} poetry install # needed for conv tests poetry add psycopg2-binary diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d37f6188..92feb296 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,7 +75,7 @@ jobs: strategy: matrix: python-version: ["3.10"] - backend-wallet-class: ["LndRestWallet", "LndWallet", "CoreLightningWallet", "CoreLightningRestWallet", "LNbitsWallet", "EclairWallet"] + backend-wallet-class: ["LndWallet", "CoreLightningWallet", "CoreLightningRestWallet", "LNbitsWallet", "EclairWallet"] with: custom-pytest: "poetry run pytest tests/regtest" python-version: ${{ matrix.python-version }} diff --git a/poetry.lock b/poetry.lock index 8289d4e0..28f5fb72 100644 --- a/poetry.lock +++ b/poetry.lock @@ -20,24 +20,25 @@ docs = ["sphinx (==7.2.6)", "sphinx-mdinclude (==0.5.3)"] [[package]] name = "anyio" -version = "3.7.1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, - {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] -test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (<0.22)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +trio = ["trio (>=0.26.1)"] [[package]] name = "asgi-lifespan" @@ -736,63 +737,73 @@ files = [ [[package]] name = "coverage" -version = "7.3.2" +version = "7.6.9" description = "Code coverage measurement for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "coverage-7.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf"}, - {file = "coverage-7.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9"}, - {file = "coverage-7.3.2-cp310-cp310-win32.whl", hash = "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f"}, - {file = "coverage-7.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611"}, - {file = "coverage-7.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c"}, - {file = "coverage-7.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312"}, - {file = "coverage-7.3.2-cp311-cp311-win32.whl", hash = "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640"}, - {file = "coverage-7.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2"}, - {file = "coverage-7.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836"}, - {file = "coverage-7.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a"}, - {file = "coverage-7.3.2-cp312-cp312-win32.whl", hash = "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb"}, - {file = "coverage-7.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed"}, - {file = "coverage-7.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738"}, - {file = "coverage-7.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76"}, - {file = "coverage-7.3.2-cp38-cp38-win32.whl", hash = "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92"}, - {file = "coverage-7.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a"}, - {file = "coverage-7.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce"}, - {file = "coverage-7.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083"}, - {file = "coverage-7.3.2-cp39-cp39-win32.whl", hash = "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce"}, - {file = "coverage-7.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f"}, - {file = "coverage-7.3.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637"}, - {file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"}, + {file = "coverage-7.6.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85d9636f72e8991a1706b2b55b06c27545448baf9f6dbf51c4004609aacd7dcb"}, + {file = "coverage-7.6.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:608a7fd78c67bee8936378299a6cb9f5149bb80238c7a566fc3e6717a4e68710"}, + {file = "coverage-7.6.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96d636c77af18b5cb664ddf12dab9b15a0cfe9c0bde715da38698c8cea748bfa"}, + {file = "coverage-7.6.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75cded8a3cff93da9edc31446872d2997e327921d8eed86641efafd350e1df1"}, + {file = "coverage-7.6.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7b15f589593110ae767ce997775d645b47e5cbbf54fd322f8ebea6277466cec"}, + {file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:44349150f6811b44b25574839b39ae35291f6496eb795b7366fef3bd3cf112d3"}, + {file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d891c136b5b310d0e702e186d70cd16d1119ea8927347045124cb286b29297e5"}, + {file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:db1dab894cc139f67822a92910466531de5ea6034ddfd2b11c0d4c6257168073"}, + {file = "coverage-7.6.9-cp310-cp310-win32.whl", hash = "sha256:41ff7b0da5af71a51b53f501a3bac65fb0ec311ebed1632e58fc6107f03b9198"}, + {file = "coverage-7.6.9-cp310-cp310-win_amd64.whl", hash = "sha256:35371f8438028fdccfaf3570b31d98e8d9eda8bb1d6ab9473f5a390969e98717"}, + {file = "coverage-7.6.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:932fc826442132dde42ee52cf66d941f581c685a6313feebed358411238f60f9"}, + {file = "coverage-7.6.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:085161be5f3b30fd9b3e7b9a8c301f935c8313dcf928a07b116324abea2c1c2c"}, + {file = "coverage-7.6.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ccc660a77e1c2bf24ddbce969af9447a9474790160cfb23de6be4fa88e3951c7"}, + {file = "coverage-7.6.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c69e42c892c018cd3c8d90da61d845f50a8243062b19d228189b0224150018a9"}, + {file = "coverage-7.6.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0824a28ec542a0be22f60c6ac36d679e0e262e5353203bea81d44ee81fe9c6d4"}, + {file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4401ae5fc52ad8d26d2a5d8a7428b0f0c72431683f8e63e42e70606374c311a1"}, + {file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98caba4476a6c8d59ec1eb00c7dd862ba9beca34085642d46ed503cc2d440d4b"}, + {file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ee5defd1733fd6ec08b168bd4f5387d5b322f45ca9e0e6c817ea6c4cd36313e3"}, + {file = "coverage-7.6.9-cp311-cp311-win32.whl", hash = "sha256:f2d1ec60d6d256bdf298cb86b78dd715980828f50c46701abc3b0a2b3f8a0dc0"}, + {file = "coverage-7.6.9-cp311-cp311-win_amd64.whl", hash = "sha256:0d59fd927b1f04de57a2ba0137166d31c1a6dd9e764ad4af552912d70428c92b"}, + {file = "coverage-7.6.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:99e266ae0b5d15f1ca8d278a668df6f51cc4b854513daab5cae695ed7b721cf8"}, + {file = "coverage-7.6.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9901d36492009a0a9b94b20e52ebfc8453bf49bb2b27bca2c9706f8b4f5a554a"}, + {file = "coverage-7.6.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abd3e72dd5b97e3af4246cdada7738ef0e608168de952b837b8dd7e90341f015"}, + {file = "coverage-7.6.9-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff74026a461eb0660366fb01c650c1d00f833a086b336bdad7ab00cc952072b3"}, + {file = "coverage-7.6.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65dad5a248823a4996724a88eb51d4b31587aa7aa428562dbe459c684e5787ae"}, + {file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22be16571504c9ccea919fcedb459d5ab20d41172056206eb2994e2ff06118a4"}, + {file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f957943bc718b87144ecaee70762bc2bc3f1a7a53c7b861103546d3a403f0a6"}, + {file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ae1387db4aecb1f485fb70a6c0148c6cdaebb6038f1d40089b1fc84a5db556f"}, + {file = "coverage-7.6.9-cp312-cp312-win32.whl", hash = "sha256:1a330812d9cc7ac2182586f6d41b4d0fadf9be9049f350e0efb275c8ee8eb692"}, + {file = "coverage-7.6.9-cp312-cp312-win_amd64.whl", hash = "sha256:b12c6b18269ca471eedd41c1b6a1065b2f7827508edb9a7ed5555e9a56dcfc97"}, + {file = "coverage-7.6.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:899b8cd4781c400454f2f64f7776a5d87bbd7b3e7f7bda0cb18f857bb1334664"}, + {file = "coverage-7.6.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:61f70dc68bd36810972e55bbbe83674ea073dd1dcc121040a08cdf3416c5349c"}, + {file = "coverage-7.6.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a289d23d4c46f1a82d5db4abeb40b9b5be91731ee19a379d15790e53031c014"}, + {file = "coverage-7.6.9-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e216d8044a356fc0337c7a2a0536d6de07888d7bcda76febcb8adc50bdbbd00"}, + {file = "coverage-7.6.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c026eb44f744acaa2bda7493dad903aa5bf5fc4f2554293a798d5606710055d"}, + {file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e77363e8425325384f9d49272c54045bbed2f478e9dd698dbc65dbc37860eb0a"}, + {file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:777abfab476cf83b5177b84d7486497e034eb9eaea0d746ce0c1268c71652077"}, + {file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:447af20e25fdbe16f26e84eb714ba21d98868705cb138252d28bc400381f6ffb"}, + {file = "coverage-7.6.9-cp313-cp313-win32.whl", hash = "sha256:d872ec5aeb086cbea771c573600d47944eea2dcba8be5f3ee649bfe3cb8dc9ba"}, + {file = "coverage-7.6.9-cp313-cp313-win_amd64.whl", hash = "sha256:fd1213c86e48dfdc5a0cc676551db467495a95a662d2396ecd58e719191446e1"}, + {file = "coverage-7.6.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ba9e7484d286cd5a43744e5f47b0b3fb457865baf07bafc6bee91896364e1419"}, + {file = "coverage-7.6.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e5ea1cf0872ee455c03e5674b5bca5e3e68e159379c1af0903e89f5eba9ccc3a"}, + {file = "coverage-7.6.9-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d10e07aa2b91835d6abec555ec8b2733347956991901eea6ffac295f83a30e4"}, + {file = "coverage-7.6.9-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13a9e2d3ee855db3dd6ea1ba5203316a1b1fd8eaeffc37c5b54987e61e4194ae"}, + {file = "coverage-7.6.9-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c38bf15a40ccf5619fa2fe8f26106c7e8e080d7760aeccb3722664c8656b030"}, + {file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d5275455b3e4627c8e7154feaf7ee0743c2e7af82f6e3b561967b1cca755a0be"}, + {file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8f8770dfc6e2c6a2d4569f411015c8d751c980d17a14b0530da2d7f27ffdd88e"}, + {file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8d2dfa71665a29b153a9681edb1c8d9c1ea50dfc2375fb4dac99ea7e21a0bcd9"}, + {file = "coverage-7.6.9-cp313-cp313t-win32.whl", hash = "sha256:5e6b86b5847a016d0fbd31ffe1001b63355ed309651851295315031ea7eb5a9b"}, + {file = "coverage-7.6.9-cp313-cp313t-win_amd64.whl", hash = "sha256:97ddc94d46088304772d21b060041c97fc16bdda13c6c7f9d8fcd8d5ae0d8611"}, + {file = "coverage-7.6.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:adb697c0bd35100dc690de83154627fbab1f4f3c0386df266dded865fc50a902"}, + {file = "coverage-7.6.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:be57b6d56e49c2739cdf776839a92330e933dd5e5d929966fbbd380c77f060be"}, + {file = "coverage-7.6.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1592791f8204ae9166de22ba7e6705fa4ebd02936c09436a1bb85aabca3e599"}, + {file = "coverage-7.6.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e12ae8cc979cf83d258acb5e1f1cf2f3f83524d1564a49d20b8bec14b637f08"}, + {file = "coverage-7.6.9-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5555cff66c4d3d6213a296b360f9e1a8e323e74e0426b6c10ed7f4d021e464"}, + {file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b9389a429e0e5142e69d5bf4a435dd688c14478a19bb901735cdf75e57b13845"}, + {file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:592ac539812e9b46046620341498caf09ca21023c41c893e1eb9dbda00a70cbf"}, + {file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a27801adef24cc30871da98a105f77995e13a25a505a0161911f6aafbd66e678"}, + {file = "coverage-7.6.9-cp39-cp39-win32.whl", hash = "sha256:8e3c3e38930cfb729cb8137d7f055e5a473ddaf1217966aa6238c88bd9fd50e6"}, + {file = "coverage-7.6.9-cp39-cp39-win_amd64.whl", hash = "sha256:e28bf44afa2b187cc9f41749138a64435bf340adfcacb5b2290c070ce99839d4"}, + {file = "coverage-7.6.9-pp39.pp310-none-any.whl", hash = "sha256:f3ca78518bc6bc92828cd11867b121891d75cae4ea9e908d72030609b996db1b"}, + {file = "coverage-7.6.9.tar.gz", hash = "sha256:4a8d8977b0c6ef5aeadcb644da9e69ae0dcfe66ec7f368c89c72e058bd71164d"}, ] [package.dependencies] @@ -2132,13 +2143,13 @@ files = [ [[package]] name = "pytest" -version = "8.3.2" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, - {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -2152,41 +2163,23 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] -[[package]] -name = "pytest-asyncio" -version = "0.21.2" -description = "Pytest support for asyncio" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest_asyncio-0.21.2-py3-none-any.whl", hash = "sha256:ab664c88bb7998f711d8039cacd4884da6430886ae8bbd4eded552ed2004f16b"}, - {file = "pytest_asyncio-0.21.2.tar.gz", hash = "sha256:d67738fc232b94b326b9d060750beb16e0074210b98dd8b58a5239fa2a154f45"}, -] - -[package.dependencies] -pytest = ">=7.0.0" - -[package.extras] -docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] - [[package]] name = "pytest-cov" -version = "4.1.0" +version = "6.0.0" description = "Pytest plugin for measuring coverage." optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, - {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, + {file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"}, + {file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"}, ] [package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} +coverage = {version = ">=7.5", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "pytest-httpserver" @@ -2649,6 +2642,7 @@ files = [ {file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b24364150738ce488333b3fb48bfa14c189a66de41cd632796fbcacb26b4585"}, {file = "SQLAlchemy-1.4.54-cp310-cp310-win32.whl", hash = "sha256:a8a72259a1652f192c68377be7011eac3c463e9892ef2948828c7d58e4829988"}, {file = "SQLAlchemy-1.4.54-cp310-cp310-win_amd64.whl", hash = "sha256:b67589f7955924865344e6eacfdcf70675e64f36800a576aa5e961f0008cde2a"}, + {file = "SQLAlchemy-1.4.54-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b05e0626ec1c391432eabb47a8abd3bf199fb74bfde7cc44a26d2b1b352c2c6e"}, {file = "SQLAlchemy-1.4.54-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13e91d6892b5fcb94a36ba061fb7a1f03d0185ed9d8a77c84ba389e5bb05e936"}, {file = "SQLAlchemy-1.4.54-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb59a11689ff3c58e7652260127f9e34f7f45478a2f3ef831ab6db7bcd72108f"}, {file = "SQLAlchemy-1.4.54-cp311-cp311-win32.whl", hash = "sha256:1390ca2d301a2708fd4425c6d75528d22f26b8f5cbc9faba1ddca136671432bc"}, @@ -3193,4 +3187,4 @@ liquid = ["wallycore"] [metadata] lock-version = "2.0" python-versions = "^3.12 | ^3.11 | ^3.10 | ^3.9" -content-hash = "f4847cf020ad21818fdad153d1845ed9c24d41d631aed1f6eec16158f6f295fb" +content-hash = "7cba29a0ac6386ae77c238cb8fccb2c1801cb7d6a3c6a079fdb9625a953145d4" diff --git a/pyproject.toml b/pyproject.toml index ecf767a4..db824a07 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,10 +66,6 @@ liquid = ["wallycore"] [tool.poetry.group.dev.dependencies] black = "^24.8.0" -# we are stuck with pytest-asyncio 0.21.x because of https://github.com/pytest-dev/pytest-asyncio/issues/706 -pytest-asyncio = "^0.21.2" -pytest = "^8.3.2" -pytest-cov = "^4.1.0" mypy = "^1.11.2" types-protobuf = "^5.27.0.20240626" pre-commit = "^3.8.0" @@ -79,6 +75,9 @@ types-passlib = "^1.7.7.20240327" openai = "^1.39.0" json5 = "^0.9.25" asgi-lifespan = "^2.1.0" +anyio = "^4.7.0" +pytest = "^8.3.4" +pytest-cov = "^6.0.0" pytest-md = "^0.2.0" pytest-httpserver = "^1.1.0" pytest-mock = "^3.14.0" diff --git a/tests/api/test_admin_api.py b/tests/api/test_admin_api.py index 69df9161..c1514144 100644 --- a/tests/api/test_admin_api.py +++ b/tests/api/test_admin_api.py @@ -4,13 +4,13 @@ from lnbits.core.models import User from lnbits.settings import Settings -@pytest.mark.asyncio +@pytest.mark.anyio async def test_admin_get_settings_permission_denied(client, from_user): response = await client.get(f"/admin/api/v1/settings?usr={from_user.id}") assert response.status_code == 401 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_admin_get_settings(client, superuser): response = await client.get(f"/admin/api/v1/settings?usr={superuser.id}") assert response.status_code == 200 @@ -18,7 +18,7 @@ async def test_admin_get_settings(client, superuser): assert "super_user" not in result -@pytest.mark.asyncio +@pytest.mark.anyio async def test_admin_update_settings(client, superuser: User, settings: Settings): new_site_title = "UPDATED SITETITLE" response = await client.put( @@ -32,7 +32,7 @@ async def test_admin_update_settings(client, superuser: User, settings: Settings assert settings.lnbits_site_title == new_site_title -@pytest.mark.asyncio +@pytest.mark.anyio async def test_admin_update_noneditable_settings(client, superuser): response = await client.put( f"/admin/api/v1/settings?usr={superuser.id}", diff --git a/tests/api/test_api.py b/tests/api/test_api.py index 88045a0f..fb7125bd 100644 --- a/tests/api/test_api.py +++ b/tests/api/test_api.py @@ -16,7 +16,7 @@ from ..helpers import ( # create account POST /api/v1/account -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_account(client, settings: Settings): settings.lnbits_allow_new_accounts = False response = await client.post("/api/v1/account", json={"name": "test"}) @@ -37,7 +37,7 @@ async def test_create_account(client, settings: Settings): # check POST and DELETE /api/v1/wallet with adminkey: # create additional wallet and delete it -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_wallet_and_delete(client, adminkey_headers_to): response = await client.post( "/api/v1/wallet", json={"name": "test"}, headers=adminkey_headers_to @@ -80,7 +80,7 @@ async def test_create_wallet_and_delete(client, adminkey_headers_to): # check GET /api/v1/wallet with inkey: wallet info, no balance -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_wallet_inkey(client, inkey_headers_to): response = await client.get("/api/v1/wallet", headers=inkey_headers_to) assert response.status_code == 200 @@ -91,7 +91,7 @@ async def test_get_wallet_inkey(client, inkey_headers_to): # check GET /api/v1/wallet with adminkey: wallet info with balance -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_wallet_adminkey(client, adminkey_headers_to): response = await client.get("/api/v1/wallet", headers=adminkey_headers_to) assert response.status_code == 200 @@ -102,21 +102,21 @@ async def test_get_wallet_adminkey(client, adminkey_headers_to): # check PUT /api/v1/wallet/newwallet: empty request where admin key is needed -@pytest.mark.asyncio +@pytest.mark.anyio async def test_put_empty_request_expected_admin_keys(client): response = await client.put("/api/v1/wallet/newwallet") assert response.status_code == 401 # check POST /api/v1/payments: empty request where invoice key is needed -@pytest.mark.asyncio +@pytest.mark.anyio async def test_post_empty_request_expected_invoice_keys(client): response = await client.post("/api/v1/payments") assert response.status_code == 401 # check POST /api/v1/payments: invoice creation -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_invoice(client, inkey_headers_to): data = await get_random_invoice_data() response = await client.post( @@ -132,7 +132,7 @@ async def test_create_invoice(client, inkey_headers_to): return invoice -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_invoice_fiat_amount(client, inkey_headers_to): data = await get_random_invoice_data() data["unit"] = "EUR" @@ -156,7 +156,7 @@ async def test_create_invoice_fiat_amount(client, inkey_headers_to): assert extra["fiat_rate"] -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.parametrize("currency", ("msat", "RRR")) async def test_create_invoice_validates_used_currency( currency, client, inkey_headers_to @@ -172,7 +172,7 @@ async def test_create_invoice_validates_used_currency( # check POST /api/v1/payments: invoice creation for internal payments only -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_internal_invoice(client, inkey_headers_to): data = await get_random_invoice_data() data["internal"] = True @@ -190,7 +190,7 @@ async def test_create_internal_invoice(client, inkey_headers_to): # check POST /api/v1/payments: invoice with custom expiry -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_invoice_custom_expiry(client, inkey_headers_to): data = await get_random_invoice_data() expiry_seconds = 600 * 6 * 24 * 31 # 31 days in the future @@ -205,7 +205,7 @@ async def test_create_invoice_custom_expiry(client, inkey_headers_to): # check POST /api/v1/payments: make payment -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_invoice( client, from_wallet_ws, invoice: Payment, adminkey_headers_from ): @@ -231,7 +231,7 @@ async def test_pay_invoice( # check GET /api/v1/payments/: payment status -@pytest.mark.asyncio +@pytest.mark.anyio async def test_check_payment_without_key(client, invoice: Payment): # check the payment status response = await client.get(f"/api/v1/payments/{invoice.payment_hash}") @@ -247,7 +247,7 @@ async def test_check_payment_without_key(client, invoice: Payment): # If postgres: it will succeed only with inkey_headers_from # If sqlite: it will succeed only with adminkey_headers_to # TODO: fix this -@pytest.mark.asyncio +@pytest.mark.anyio async def test_check_payment_with_key(client, invoice: Payment, inkey_headers_from): # check the payment status response = await client.get( @@ -261,7 +261,7 @@ async def test_check_payment_with_key(client, invoice: Payment, inkey_headers_fr # check POST /api/v1/payments: payment with wrong key type -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_invoice_wrong_key(client, invoice, adminkey_headers_from): data = {"out": True, "bolt11": invoice.bolt11} # try payment with wrong key @@ -274,7 +274,7 @@ async def test_pay_invoice_wrong_key(client, invoice, adminkey_headers_from): # check POST /api/v1/payments: payment with self payment -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_invoice_self_payment(client, adminkey_headers_from): create_invoice = CreateInvoice(out=False, amount=1000, memo="test") response = await client.post( @@ -292,7 +292,7 @@ async def test_pay_invoice_self_payment(client, adminkey_headers_from): # check POST /api/v1/payments: payment with invoice key [should fail] -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_invoice_invoicekey(client, invoice, inkey_headers_from): data = {"out": True, "bolt11": invoice.bolt11} # try payment with invoice key @@ -303,7 +303,7 @@ async def test_pay_invoice_invoicekey(client, invoice, inkey_headers_from): # check POST /api/v1/payments: payment with admin key, trying to pay twice [should fail] -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_invoice_adminkey(client, invoice, adminkey_headers_from): data = {"out": True, "bolt11": invoice.bolt11} # try payment with admin key @@ -313,7 +313,7 @@ async def test_pay_invoice_adminkey(client, invoice, adminkey_headers_from): assert response.status_code > 300 # should fail -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_payments(client, inkey_fresh_headers_to, fake_payments): fake_data, filters = fake_payments @@ -348,7 +348,7 @@ async def test_get_payments(client, inkey_fresh_headers_to, fake_payments): assert len(payments) == 2 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_payments_paginated(client, inkey_fresh_headers_to, fake_payments): fake_data, filters = fake_payments @@ -363,7 +363,7 @@ async def test_get_payments_paginated(client, inkey_fresh_headers_to, fake_payme assert paginated["total"] == len(fake_data) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_payments_history(client, inkey_fresh_headers_to, fake_payments): fake_data, filters = fake_payments @@ -393,7 +393,7 @@ async def test_get_payments_history(client, inkey_fresh_headers_to, fake_payment # check POST /api/v1/payments/decode -@pytest.mark.asyncio +@pytest.mark.anyio async def test_decode_invoice(client, invoice: Payment): data = {"data": invoice.bolt11} response = await client.post( @@ -405,7 +405,7 @@ async def test_decode_invoice(client, invoice: Payment): # check api_payment() internal function call (NOT API): payment status -@pytest.mark.asyncio +@pytest.mark.anyio async def test_api_payment_without_key(invoice: Payment): # check the payment status response = await api_payment(invoice.payment_hash) @@ -416,7 +416,7 @@ async def test_api_payment_without_key(invoice: Payment): # check api_payment() internal function call (NOT API): payment status -@pytest.mark.asyncio +@pytest.mark.anyio async def test_api_payment_with_key(invoice: Payment, inkey_headers_from): # check the payment status response = await api_payment(invoice.payment_hash, inkey_headers_from["X-Api-Key"]) @@ -426,7 +426,7 @@ async def test_api_payment_with_key(invoice: Payment, inkey_headers_from): # check POST /api/v1/payments: invoice creation with a description hash -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_invoice_with_description_hash(client, inkey_headers_to): data = await get_random_invoice_data() description = "asdasdasd" @@ -443,7 +443,7 @@ async def test_create_invoice_with_description_hash(client, inkey_headers_to): return invoice -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_invoice_with_unhashed_description(client, inkey_headers_to): data = await get_random_invoice_data() description = "test description" @@ -461,7 +461,7 @@ async def test_create_invoice_with_unhashed_description(client, inkey_headers_to return invoice -@pytest.mark.asyncio +@pytest.mark.anyio async def test_update_wallet(client, adminkey_headers_from): name = "new name" currency = "EUR" @@ -481,7 +481,7 @@ async def test_update_wallet(client, adminkey_headers_from): assert response.json()["name"] == name -@pytest.mark.asyncio +@pytest.mark.anyio async def test_fiat_tracking(client, adminkey_headers_from, settings: Settings): async def create_invoice(): data = await get_random_invoice_data() @@ -522,7 +522,7 @@ async def test_fiat_tracking(client, adminkey_headers_from, settings: Settings): assert extra["wallet_fiat_rate"] -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.parametrize( "lnurl_response_data, callback_response_data, expected_response", [ diff --git a/tests/api/test_auth.py b/tests/api/test_auth.py index efa27a2f..09627935 100644 --- a/tests/api/test_auth.py +++ b/tests/api/test_auth.py @@ -27,11 +27,12 @@ nostr_event = { private_key = secp256k1.PrivateKey( bytes.fromhex("6e00ecda7d3c8945f07b7d6ecc18cfff34c07bc99677309e2b9310d9fc1bb138") ) +assert private_key.pubkey, "Pubkey not created." pubkey_hex = private_key.pubkey.serialize().hex()[2:] ################################ LOGIN ################################ -@pytest.mark.asyncio +@pytest.mark.anyio async def test_login_bad_user(http_client: AsyncClient): response = await http_client.post( "/api/v1/auth", json={"username": "non_existing_user", "password": "secret1234"} @@ -41,7 +42,7 @@ async def test_login_bad_user(http_client: AsyncClient): assert response.json().get("detail") == "Invalid credentials." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_login_alan_usr(user_alan: User, http_client: AsyncClient): response = await http_client.post("/api/v1/auth/usr", json={"usr": user_alan.id}) @@ -60,7 +61,7 @@ async def test_login_alan_usr(user_alan: User, http_client: AsyncClient): assert alan["email"] == user_alan.email -@pytest.mark.asyncio +@pytest.mark.anyio async def test_login_usr_not_allowed( user_alan: User, http_client: AsyncClient, settings: Settings ): @@ -81,7 +82,7 @@ async def test_login_usr_not_allowed( ), "Expected access token after login." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_login_alan_username_password_ok( user_alan: User, http_client: AsyncClient, settings: Settings ): @@ -119,7 +120,7 @@ async def test_login_alan_username_password_ok( ), f"Expected 1 default wallet, not {len(user.wallets)}." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_login_alan_email_password_ok(user_alan: User, http_client: AsyncClient): response = await http_client.post( "/api/v1/auth", json={"username": user_alan.email, "password": "secret1234"} @@ -130,7 +131,7 @@ async def test_login_alan_email_password_ok(user_alan: User, http_client: AsyncC assert access_token is not None -@pytest.mark.asyncio +@pytest.mark.anyio async def test_login_alan_password_nok(user_alan: User, http_client: AsyncClient): response = await http_client.post( "/api/v1/auth", json={"username": user_alan.username, "password": "bad_pasword"} @@ -140,7 +141,7 @@ async def test_login_alan_password_nok(user_alan: User, http_client: AsyncClient assert response.json().get("detail") == "Invalid credentials." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_login_username_password_not_allowed( user_alan: User, http_client: AsyncClient, settings: Settings ): @@ -165,7 +166,7 @@ async def test_login_username_password_not_allowed( assert response.json().get("access_token") is not None -@pytest.mark.asyncio +@pytest.mark.anyio async def test_login_alan_change_auth_secret_key( user_alan: User, http_client: AsyncClient, settings: Settings ): @@ -196,7 +197,7 @@ async def test_login_alan_change_auth_secret_key( ################################ REGISTER WITH PASSWORD ################################ -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_ok(http_client: AsyncClient): tiny_id = shortuuid.uuid()[:8] response = await http_client.post( @@ -229,7 +230,7 @@ async def test_register_ok(http_client: AsyncClient): ), f"Expected 1 default wallet, not {len(user.wallets)}." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_email_twice(http_client: AsyncClient): tiny_id = shortuuid.uuid()[:8] response = await http_client.post( @@ -260,7 +261,7 @@ async def test_register_email_twice(http_client: AsyncClient): assert response.json().get("detail") == "Email already exists." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_username_twice(http_client: AsyncClient): tiny_id = shortuuid.uuid()[:8] response = await http_client.post( @@ -290,7 +291,7 @@ async def test_register_username_twice(http_client: AsyncClient): assert response.json().get("detail") == "Username already exists." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_passwords_do_not_match(http_client: AsyncClient): tiny_id = shortuuid.uuid()[:8] response = await http_client.post( @@ -307,7 +308,7 @@ async def test_register_passwords_do_not_match(http_client: AsyncClient): assert response.json().get("detail") == "Passwords do not match." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_bad_email(http_client: AsyncClient): tiny_id = shortuuid.uuid()[:8] response = await http_client.post( @@ -325,7 +326,7 @@ async def test_register_bad_email(http_client: AsyncClient): ################################ CHANGE PASSWORD ################################ -@pytest.mark.asyncio +@pytest.mark.anyio async def test_change_password_ok(http_client: AsyncClient, settings: Settings): tiny_id = shortuuid.uuid()[:8] response = await http_client.post( @@ -377,7 +378,7 @@ async def test_change_password_ok(http_client: AsyncClient, settings: Settings): assert response.json().get("access_token") is not None, "Access token created." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_change_password_not_authenticated(http_client: AsyncClient): tiny_id = shortuuid.uuid()[:8] response = await http_client.put( @@ -395,7 +396,7 @@ async def test_change_password_not_authenticated(http_client: AsyncClient): assert response.json().get("detail") == "Missing user ID or access token." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_alan_change_password_old_nok(user_alan: User, http_client: AsyncClient): response = await http_client.post("/api/v1/auth/usr", json={"usr": user_alan.id}) @@ -419,7 +420,7 @@ async def test_alan_change_password_old_nok(user_alan: User, http_client: AsyncC assert response.json().get("detail") == "Invalid old password." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_alan_change_password_different_user( user_alan: User, http_client: AsyncClient ): @@ -445,7 +446,7 @@ async def test_alan_change_password_different_user( assert response.json().get("detail") == "Invalid user ID." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_alan_change_password_auth_threshold_expired( user_alan: User, http_client: AsyncClient, settings: Settings ): @@ -481,12 +482,13 @@ async def test_alan_change_password_auth_threshold_expired( ################################ REGISTER PUBLIC KEY ################################ -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_nostr_ok(http_client: AsyncClient, settings: Settings): event = {**nostr_event} event["created_at"] = int(time.time()) private_key = secp256k1.PrivateKey(bytes.fromhex(os.urandom(32).hex())) + assert private_key.pubkey, "Pubkey not created." pubkey_hex = private_key.pubkey.serialize().hex()[2:] event_signed = sign_event(event, pubkey_hex, private_key) base64_event = base64.b64encode(json.dumps(event_signed).encode()).decode("ascii") @@ -521,7 +523,7 @@ async def test_register_nostr_ok(http_client: AsyncClient, settings: Settings): ), f"Expected 1 default wallet, not {len(user.wallets)}." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_nostr_not_allowed(http_client: AsyncClient, settings: Settings): # exclude 'nostr_auth_nip98' settings.auth_allowed_methods = [AuthMethods.username_and_password.value] @@ -536,7 +538,7 @@ async def test_register_nostr_not_allowed(http_client: AsyncClient, settings: Se settings.auth_allowed_methods = AuthMethods.all() -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_nostr_bad_header(http_client: AsyncClient): response = await http_client.post("/api/v1/auth/nostr") @@ -559,7 +561,7 @@ async def test_register_nostr_bad_header(http_client: AsyncClient): assert response.json().get("detail") == "Nostr login event cannot be parsed." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_nostr_bad_event(http_client: AsyncClient, settings: Settings): settings.auth_allowed_methods = AuthMethods.all() base64_event = base64.b64encode(json.dumps(nostr_event).encode()).decode("ascii") @@ -587,7 +589,7 @@ async def test_register_nostr_bad_event(http_client: AsyncClient, settings: Sett assert response.json().get("detail") == "Nostr login event is not valid." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_nostr_bad_event_kind(http_client: AsyncClient): event_bad_kind = {**nostr_event} event_bad_kind["kind"] = "12345" @@ -604,7 +606,7 @@ async def test_register_nostr_bad_event_kind(http_client: AsyncClient): assert response.json().get("detail") == "Invalid event kind." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_nostr_bad_event_tag_u(http_client: AsyncClient): event_bad_kind = {**nostr_event} event_bad_kind["created_at"] = int(time.time()) @@ -636,7 +638,7 @@ async def test_register_nostr_bad_event_tag_u(http_client: AsyncClient): assert response.json().get("detail") == "Invalid value for tag 'method'." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_register_nostr_bad_event_tag_menthod(http_client: AsyncClient): event_bad_kind = {**nostr_event} event_bad_kind["created_at"] = int(time.time()) @@ -672,6 +674,7 @@ async def test_register_nostr_bad_event_tag_menthod(http_client: AsyncClient): ################################ CHANGE PUBLIC KEY ################################ +@pytest.mark.anyio async def test_change_pubkey_npub_ok(http_client: AsyncClient, settings: Settings): tiny_id = shortuuid.uuid()[:8] response = await http_client.post( @@ -692,6 +695,7 @@ async def test_change_pubkey_npub_ok(http_client: AsyncClient, settings: Setting access_token_payload = AccessTokenPayload(**payload) private_key = secp256k1.PrivateKey(bytes.fromhex(os.urandom(32).hex())) + assert private_key.pubkey, "Pubkey not created." pubkey_hex = private_key.pubkey.serialize().hex()[2:] npub = hex_to_npub(pubkey_hex) @@ -711,7 +715,7 @@ async def test_change_pubkey_npub_ok(http_client: AsyncClient, settings: Setting assert user.pubkey == pubkey_hex -@pytest.mark.asyncio +@pytest.mark.anyio async def test_change_pubkey_ok( http_client: AsyncClient, user_alan: User, settings: Settings ): @@ -734,6 +738,7 @@ async def test_change_pubkey_ok( access_token_payload = AccessTokenPayload(**payload) private_key = secp256k1.PrivateKey(bytes.fromhex(os.urandom(32).hex())) + assert private_key.pubkey, "Pubkey not created." pubkey_hex = private_key.pubkey.serialize().hex()[2:] response = await http_client.put( @@ -798,7 +803,7 @@ async def test_change_pubkey_ok( assert response.json().get("detail") == "Public key already in use." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_change_pubkey_not_authenticated( http_client: AsyncClient, user_alan: User ): @@ -814,7 +819,7 @@ async def test_change_pubkey_not_authenticated( assert response.json().get("detail") == "Missing user ID or access token." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_change_pubkey_other_user(http_client: AsyncClient, user_alan: User): response = await http_client.post("/api/v1/auth/usr", json={"usr": user_alan.id}) @@ -834,7 +839,7 @@ async def test_change_pubkey_other_user(http_client: AsyncClient, user_alan: Use assert response.json().get("detail") == "Invalid user ID." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_alan_change_pubkey_auth_threshold_expired( user_alan: User, http_client: AsyncClient, settings: Settings ): @@ -865,7 +870,7 @@ async def test_alan_change_pubkey_auth_threshold_expired( ################################ RESET PASSWORD ################################ -@pytest.mark.asyncio +@pytest.mark.anyio async def test_request_reset_key_ok(http_client: AsyncClient, settings: Settings): tiny_id = shortuuid.uuid()[:8] response = await http_client.post( @@ -917,7 +922,7 @@ async def test_request_reset_key_ok(http_client: AsyncClient, settings: Settings assert access_token is not None -@pytest.mark.asyncio +@pytest.mark.anyio async def test_request_reset_key_user_not_found(http_client: AsyncClient): user_id = "926abb2ab59a48ebb2485bcceb58d05e" reset_key = await api_users_reset_password(user_id) @@ -937,7 +942,7 @@ async def test_request_reset_key_user_not_found(http_client: AsyncClient): assert response.json().get("detail") == "User not found." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_reset_username_password_not_allowed( http_client: AsyncClient, settings: Settings ): @@ -964,7 +969,7 @@ async def test_reset_username_password_not_allowed( ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_reset_username_passwords_do_not_matcj( http_client: AsyncClient, user_alan: User ): @@ -985,7 +990,7 @@ async def test_reset_username_passwords_do_not_matcj( assert response.json().get("detail") == "Passwords do not match." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_reset_username_password_bad_key(http_client: AsyncClient): response = await http_client.put( @@ -1000,7 +1005,7 @@ async def test_reset_username_password_bad_key(http_client: AsyncClient): assert response.json().get("detail") == "Invalid reset key." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_reset_password_auth_threshold_expired( user_alan: User, http_client: AsyncClient, settings: Settings ): diff --git a/tests/api/test_generic.py b/tests/api/test_generic.py index 3e7b3a23..23656bb1 100644 --- a/tests/api/test_generic.py +++ b/tests/api/test_generic.py @@ -1,21 +1,21 @@ import pytest -@pytest.mark.asyncio +@pytest.mark.anyio async def test_core_views_generic(client): response = await client.get("/") assert response.status_code == 200, f"{response.url} {response.status_code}" # check GET /wallet: wrong user, expect 400 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_wallet_with_nonexistent_user(client): response = await client.get("wallet", params={"usr": "1"}) assert response.status_code == 400, f"{response.url} {response.status_code}" # check GET /wallet: wallet and user -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_wallet_with_user_and_wallet(client, to_user, to_wallet): response = await client.get( "wallet", params={"usr": to_user.id, "wal": to_wallet.id} @@ -24,28 +24,28 @@ async def test_get_wallet_with_user_and_wallet(client, to_user, to_wallet): # check GET /wallet: wrong wallet and user, expect 400 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_wallet_with_user_and_wrong_wallet(client, to_user): response = await client.get("wallet", params={"usr": to_user.id, "wal": "1"}) assert response.status_code == 400, f"{response.url} {response.status_code}" # check GET /extensions: extensions list -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_extensions(client, to_user): response = await client.get("extensions", params={"usr": to_user.id}) assert response.status_code == 200, f"{response.url} {response.status_code}" # check GET /extensions: extensions list wrong user, expect 400 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_extensions_wrong_user(client): response = await client.get("extensions", params={"usr": "1"}) assert response.status_code == 400, f"{response.url} {response.status_code}" # check GET /extensions: no user given, expect code 400 bad request -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_extensions_no_user(client): response = await client.get("extensions") # bad request diff --git a/tests/api/test_public_api.py b/tests/api/test_public_api.py index 59152b66..1f42b530 100644 --- a/tests/api/test_public_api.py +++ b/tests/api/test_public_api.py @@ -4,14 +4,14 @@ from lnbits.core.models import Payment # check if the client is working -@pytest.mark.asyncio +@pytest.mark.anyio async def test_core_views_generic(client): response = await client.get("/") assert response.status_code == 200 # check GET /public/v1/payment/{payment_hash}: correct hash [should pass] -@pytest.mark.asyncio +@pytest.mark.anyio async def test_api_public_payment_longpolling(client, invoice: Payment): response = await client.get(f"/public/v1/payment/{invoice.payment_hash}") assert response.status_code < 300 @@ -19,7 +19,7 @@ async def test_api_public_payment_longpolling(client, invoice: Payment): # check GET /public/v1/payment/{payment_hash}: wrong hash [should fail] -@pytest.mark.asyncio +@pytest.mark.anyio async def test_api_public_payment_longpolling_wrong_hash(client, invoice: Payment): response = await client.get(f"/public/v1/payment/{invoice.payment_hash + '0'*64}") assert response.status_code == 404 diff --git a/tests/api/test_webpush_api.py b/tests/api/test_webpush_api.py index 36cc7c75..fa493090 100644 --- a/tests/api/test_webpush_api.py +++ b/tests/api/test_webpush_api.py @@ -3,7 +3,7 @@ from http import HTTPStatus import pytest -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create___bad_body(client, adminkey_headers_from): response = await client.post( "/api/v1/webpush", @@ -13,7 +13,7 @@ async def test_create___bad_body(client, adminkey_headers_from): assert response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create___missing_fields(client, adminkey_headers_from): response = await client.post( "/api/v1/webpush", @@ -23,7 +23,7 @@ async def test_create___missing_fields(client, adminkey_headers_from): assert response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create___bad_access_key(client, inkey_headers_from): response = await client.post( "/api/v1/webpush", @@ -33,7 +33,7 @@ async def test_create___bad_access_key(client, inkey_headers_from): assert response.status_code == HTTPStatus.UNAUTHORIZED -@pytest.mark.asyncio +@pytest.mark.anyio async def test_delete__bad_endpoint_format(client, adminkey_headers_from): response = await client.delete( "/api/v1/webpush", @@ -43,7 +43,7 @@ async def test_delete__bad_endpoint_format(client, adminkey_headers_from): assert response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR -@pytest.mark.asyncio +@pytest.mark.anyio async def test_delete__no_endpoint_param(client, adminkey_headers_from): response = await client.delete( "/api/v1/webpush", @@ -52,7 +52,7 @@ async def test_delete__no_endpoint_param(client, adminkey_headers_from): assert response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR -@pytest.mark.asyncio +@pytest.mark.anyio async def test_delete__no_endpoint_found(client, adminkey_headers_from): response = await client.delete( "/api/v1/webpush", @@ -63,7 +63,7 @@ async def test_delete__no_endpoint_found(client, adminkey_headers_from): assert response.json()["count"] == 0 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_delete__bad_access_key(client, inkey_headers_from): response = await client.delete( "/api/v1/webpush", @@ -72,7 +72,7 @@ async def test_delete__bad_access_key(client, inkey_headers_from): assert response.status_code == HTTPStatus.UNAUTHORIZED -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_and_delete(client, adminkey_headers_from): response = await client.post( "/api/v1/webpush", diff --git a/tests/conftest.py b/tests/conftest.py index 2f46608e..76b84848 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,18 +1,9 @@ -# ruff: noqa: E402 import asyncio from datetime import datetime, timezone - -import uvloop - -from lnbits.core.views.payment_api import _api_payments_create_invoice -from lnbits.wallets.fake import FakeWallet - -asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) - from uuid import uuid4 import pytest -import pytest_asyncio +import uvloop from asgi_lifespan import LifespanManager from fastapi.testclient import TestClient from httpx import ASGITransport, AsyncClient @@ -29,15 +20,24 @@ from lnbits.core.crud import ( ) from lnbits.core.models import Account, CreateInvoice, PaymentState, User from lnbits.core.services import create_user_account, update_wallet_balance +from lnbits.core.views.payment_api import _api_payments_create_invoice from lnbits.db import DB_TYPE, SQLITE, Database from lnbits.settings import AuthMethods, Settings from lnbits.settings import settings as lnbits_settings +from lnbits.wallets.fake import FakeWallet from tests.helpers import ( get_random_invoice_data, ) +asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) -@pytest_asyncio.fixture(scope="session") + +@pytest.fixture(scope="session") +def anyio_backend(): + return "asyncio" + + +@pytest.fixture(scope="session") def settings(): # override settings for tests lnbits_settings.lnbits_admin_extensions = [] @@ -57,15 +57,8 @@ def run_before_and_after_tests(settings: Settings): _settings_cleanup(settings) -@pytest_asyncio.fixture(scope="session") -def event_loop(): - loop = asyncio.get_event_loop() - yield loop - loop.close() - - # use session scope to run once before and once after all tests -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def app(settings: Settings): app = create_app() async with LifespanManager(app) as manager: @@ -73,7 +66,7 @@ async def app(settings: Settings): yield manager.app -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def client(app, settings: Settings): url = f"http://{settings.host}:{settings.port}" async with AsyncClient(transport=ASGITransport(app=app), base_url=url) as client: @@ -81,7 +74,7 @@ async def client(app, settings: Settings): # function scope -@pytest_asyncio.fixture(scope="function") +@pytest.fixture(scope="function") async def http_client(app, settings: Settings): url = f"http://{settings.host}:{settings.port}" @@ -94,12 +87,12 @@ def test_client(app): return TestClient(app) -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def db(): yield Database("database") -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def user_alan(): account = await get_account_by_username("alan") if account: @@ -116,13 +109,13 @@ async def user_alan(): yield user -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def from_user(): user = await create_user_account() yield user -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def from_wallet(from_user): user = from_user @@ -134,7 +127,7 @@ async def from_wallet(from_user): yield wallet -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def to_wallet_pagination_tests(to_user): user = to_user wallet = await create_wallet( @@ -143,7 +136,7 @@ async def to_wallet_pagination_tests(to_user): yield wallet -@pytest_asyncio.fixture +@pytest.fixture async def from_wallet_ws(from_wallet, test_client): # wait a bit in order to avoid receiving topup notification await asyncio.sleep(0.1) @@ -151,7 +144,7 @@ async def from_wallet_ws(from_wallet, test_client): yield ws -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def to_user(): user = await create_user_account() yield user @@ -165,7 +158,7 @@ def from_super_user(from_user: User, settings: Settings): settings.super_user = prev -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def superuser(settings: Settings): account = await get_account(settings.super_user) assert account, "Superuser not found" @@ -173,7 +166,7 @@ async def superuser(settings: Settings): yield user -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def to_wallet(to_user): user = to_user wallet = await create_wallet(user_id=user.id, wallet_name="test_wallet_to") @@ -184,14 +177,14 @@ async def to_wallet(to_user): yield wallet -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def to_fresh_wallet(to_user): user = to_user wallet = await create_wallet(user_id=user.id, wallet_name="test_wallet_to_fresh") yield wallet -@pytest_asyncio.fixture +@pytest.fixture async def to_wallet_ws(to_wallet, test_client): # wait a bit in order to avoid receiving topup notification await asyncio.sleep(0.1) @@ -199,7 +192,7 @@ async def to_wallet_ws(to_wallet, test_client): yield ws -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def inkey_fresh_headers_to(to_fresh_wallet): wallet = to_fresh_wallet yield { @@ -208,7 +201,7 @@ async def inkey_fresh_headers_to(to_fresh_wallet): } -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def inkey_headers_from(from_wallet): wallet = from_wallet yield { @@ -217,7 +210,7 @@ async def inkey_headers_from(from_wallet): } -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def adminkey_headers_from(from_wallet): wallet = from_wallet yield { @@ -226,7 +219,7 @@ async def adminkey_headers_from(from_wallet): } -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def inkey_headers_to(to_wallet): wallet = to_wallet yield { @@ -235,7 +228,7 @@ async def inkey_headers_to(to_wallet): } -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def adminkey_headers_to(to_wallet): wallet = to_wallet yield { @@ -244,7 +237,7 @@ async def adminkey_headers_to(to_wallet): } -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def invoice(to_wallet): data = await get_random_invoice_data() invoice_data = CreateInvoice(**data) @@ -253,12 +246,12 @@ async def invoice(to_wallet): del invoice -@pytest_asyncio.fixture(scope="function") +@pytest.fixture(scope="function") async def external_funding_source(): yield FakeWallet() -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def fake_payments(client, inkey_fresh_headers_to): ts = datetime.now(timezone.utc).timestamp() diff --git a/tests/regtest/conftest.py b/tests/regtest/conftest.py index cce10b4b..ac61052a 100644 --- a/tests/regtest/conftest.py +++ b/tests/regtest/conftest.py @@ -1,23 +1,28 @@ -import pytest_asyncio +import pytest from .helpers import get_hold_invoice, get_real_invoice -@pytest_asyncio.fixture(scope="function") +@pytest.fixture(scope="session") +def anyio_backend(): + return "asyncio" + + +@pytest.fixture(scope="function") async def hold_invoice(): invoice = get_hold_invoice(100) yield invoice del invoice -@pytest_asyncio.fixture(scope="function") +@pytest.fixture(scope="function") async def real_invoice(): invoice = get_real_invoice(100) yield {"bolt11": invoice["payment_request"]} del invoice -@pytest_asyncio.fixture(scope="function") +@pytest.fixture(scope="function") async def real_amountless_invoice(): invoice = get_real_invoice(0) yield invoice["payment_request"] diff --git a/tests/regtest/test_real_invoice.py b/tests/regtest/test_real_invoice.py index a36dd728..46e6f28b 100644 --- a/tests/regtest/test_real_invoice.py +++ b/tests/regtest/test_real_invoice.py @@ -24,7 +24,7 @@ async def get_node_balance_sats(): return balance.node_balance_msats / 1000 -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.skipif(is_fake, reason="this only works in regtest") async def test_pay_real_invoice( client, real_invoice, adminkey_headers_from, inkey_headers_from, from_wallet_ws @@ -60,7 +60,7 @@ async def test_pay_real_invoice( assert prev_balance - balance == 100 -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.skipif(is_fake, reason="this only works in regtest") async def test_create_real_invoice(client, adminkey_headers_from, inkey_headers_from): prev_balance = await get_node_balance_sats() @@ -106,7 +106,7 @@ async def test_create_real_invoice(client, adminkey_headers_from, inkey_headers_ await task -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.skipif(is_fake, reason="this only works in regtest") async def test_pay_real_invoice_set_pending_and_check_state( client, real_invoice, adminkey_headers_from, inkey_headers_from @@ -145,7 +145,7 @@ async def test_pay_real_invoice_set_pending_and_check_state( assert payment.success -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.skipif(is_fake, reason="this only works in regtest") async def test_pay_hold_invoice_check_pending( client, hold_invoice, adminkey_headers_from @@ -174,7 +174,7 @@ async def test_pay_hold_invoice_check_pending( assert payment_db_after_settlement -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.skipif(is_fake, reason="this only works in regtest") async def test_pay_hold_invoice_check_pending_and_fail( client, hold_invoice, adminkey_headers_from @@ -209,7 +209,7 @@ async def test_pay_hold_invoice_check_pending_and_fail( assert payment_db_after_settlement.failed is True -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.skipif(is_fake, reason="this only works in regtest") async def test_pay_hold_invoice_check_pending_and_fail_cancel_payment_task_in_meantime( client, hold_invoice, adminkey_headers_from @@ -248,7 +248,7 @@ async def test_pay_hold_invoice_check_pending_and_fail_cancel_payment_task_in_me assert status.failed -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.skipif(is_fake, reason="this only works in regtest") async def test_receive_real_invoice_set_pending_and_check_state( client, adminkey_headers_from, inkey_headers_from @@ -308,7 +308,7 @@ async def test_receive_real_invoice_set_pending_and_check_state( await task -@pytest.mark.asyncio +@pytest.mark.anyio async def test_check_fee_reserve(client, adminkey_headers_from): # if regtest, create a real invoice, otherwise create an internal invoice # call /api/v1/payments/fee-reserve?invoice=... with it and check if the fee reserve diff --git a/tests/regtest/test_services_create_invoice.py b/tests/regtest/test_services_create_invoice.py index 1e181d1e..fb854f55 100644 --- a/tests/regtest/test_services_create_invoice.py +++ b/tests/regtest/test_services_create_invoice.py @@ -10,7 +10,7 @@ from lnbits.wallets.base import PaymentStatus description = "test create invoice" -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_invoice(from_wallet): payment = await create_invoice( wallet_id=from_wallet.id, @@ -28,7 +28,7 @@ async def test_create_invoice(from_wallet): assert status.pending -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_internal_invoice(from_wallet): payment = await create_invoice( wallet_id=from_wallet.id, amount=1000, memo=description, internal=True diff --git a/tests/regtest/test_services_pay_invoice.py b/tests/regtest/test_services_pay_invoice.py index 04c51243..4c373b22 100644 --- a/tests/regtest/test_services_pay_invoice.py +++ b/tests/regtest/test_services_pay_invoice.py @@ -9,7 +9,7 @@ from lnbits.exceptions import PaymentError description = "test pay invoice" -@pytest.mark.asyncio +@pytest.mark.anyio async def test_services_pay_invoice(to_wallet, real_invoice): payment = await pay_invoice( wallet_id=to_wallet.id, @@ -21,7 +21,7 @@ async def test_services_pay_invoice(to_wallet, real_invoice): assert payment.memo == description -@pytest.mark.asyncio +@pytest.mark.anyio async def test_services_pay_invoice_0_amount_invoice( to_wallet, real_amountless_invoice ): diff --git a/tests/regtest/test_x_node_api.py b/tests/regtest/test_x_node_api.py index 28210606..0df07f1e 100644 --- a/tests/regtest/test_x_node_api.py +++ b/tests/regtest/test_x_node_api.py @@ -7,7 +7,6 @@ from pydantic import parse_obj_as from lnbits import bolt11 from lnbits.nodes.base import ChannelPoint, ChannelState, NodeChannel -from tests.conftest import pytest_asyncio from ..helpers import ( funding_source, @@ -24,7 +23,7 @@ pytestmark = pytest.mark.skipif( ) -@pytest_asyncio.fixture() +@pytest.fixture() async def node_client(client, from_super_user, settings): settings.lnbits_node_ui = True settings.lnbits_public_node_ui = False @@ -36,39 +35,39 @@ async def node_client(client, from_super_user, settings): settings.lnbits_node_ui = False -@pytest_asyncio.fixture() +@pytest.fixture() async def public_node_client(node_client, settings): settings.lnbits_public_node_ui = True yield node_client settings.lnbits_public_node_ui = False -@pytest.mark.asyncio +@pytest.mark.anyio async def test_node_info_not_found(client, from_super_user, settings): settings.lnbits_node_ui = False response = await client.get("/node/api/v1/info", params={"usr": from_super_user.id}) assert response.status_code == HTTPStatus.SERVICE_UNAVAILABLE -@pytest.mark.asyncio +@pytest.mark.anyio async def test_public_node_info_not_found(node_client): response = await node_client.get("/node/public/api/v1/info") assert response.status_code == HTTPStatus.SERVICE_UNAVAILABLE -@pytest.mark.asyncio +@pytest.mark.anyio async def test_public_node_info(public_node_client): response = await public_node_client.get("/node/public/api/v1/info") assert response.status_code == 200 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_node_info(node_client): response = await node_client.get("/node/api/v1/info") assert response.status_code == 200 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_node_invoices(inkey_headers_from, node_client): data = await get_random_invoice_data() response = await node_client.post( @@ -83,7 +82,7 @@ async def test_node_invoices(inkey_headers_from, node_client): assert invoices[0]["payment_hash"] == invoice["payment_hash"] -@pytest.mark.asyncio +@pytest.mark.anyio async def test_node_payments(node_client, real_invoice, adminkey_headers_from): response = await node_client.post( "/api/v1/payments", json=real_invoice, headers=adminkey_headers_from @@ -100,7 +99,7 @@ async def test_node_payments(node_client, real_invoice, adminkey_headers_from): ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_channel_management(node_client): async def get_channels(): response = await node_client.get("/node/api/v1/channels") @@ -147,7 +146,7 @@ async def test_channel_management(node_client): mine_blocks(5) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_peer_management(node_client): connect_uri = get_unconnected_node_uri() peer_id = connect_uri.split("@")[0] @@ -171,7 +170,7 @@ async def test_peer_management(node_client): assert response.status_code == 400 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_connect_invalid_uri(node_client): response = await node_client.post("/node/api/v1/peers", json={"uri": "invalid"}) assert response.status_code == 400 diff --git a/tests/unit/test_cache.py b/tests/unit/test_cache.py index 4191f6e3..f7ec4a90 100644 --- a/tests/unit/test_cache.py +++ b/tests/unit/test_cache.py @@ -3,13 +3,12 @@ import asyncio import pytest from lnbits.utils.cache import Cache -from tests.conftest import pytest_asyncio key = "foo" value = "bar" -@pytest_asyncio.fixture +@pytest.fixture async def cache(): cache = Cache(interval=0.1) @@ -18,7 +17,7 @@ async def cache(): task.cancel() -@pytest.mark.asyncio +@pytest.mark.anyio async def test_cache_get_set(cache): cache.set(key, value) assert cache.get(key) == value @@ -26,7 +25,7 @@ async def test_cache_get_set(cache): assert cache.get("i-dont-exist", default="default") == "default" -@pytest.mark.asyncio +@pytest.mark.anyio async def test_cache_expiry(cache): # gets expired by `get` call cache.set(key, value, expiry=0.01) @@ -40,7 +39,7 @@ async def test_cache_expiry(cache): assert not cache.get(key) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_cache_pop(cache): cache.set(key, value) assert cache.pop(key) == value @@ -48,7 +47,7 @@ async def test_cache_pop(cache): assert cache.pop(key, default="a") == "a" -@pytest.mark.asyncio +@pytest.mark.anyio async def test_cache_coro(cache): called = 0 diff --git a/tests/unit/test_db.py b/tests/unit/test_db.py index e0ffc1b3..e73ccd5e 100644 --- a/tests/unit/test_db.py +++ b/tests/unit/test_db.py @@ -11,7 +11,7 @@ from lnbits.core.crud import ( from lnbits.db import POSTGRES -@pytest.mark.asyncio +@pytest.mark.anyio async def test_date_conversion(db): if db.type == POSTGRES: row = await db.fetchone("SELECT now()::date as now") @@ -19,7 +19,7 @@ async def test_date_conversion(db): # make test to create wallet and delete wallet -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_wallet_and_delete_wallet(app, to_user): # create wallet wallet = await create_wallet(user_id=to_user.id, wallet_name="test_wallet_delete") diff --git a/tests/unit/test_db_fetch_page.py b/tests/unit/test_db_fetch_page.py index ba0c8409..58a03259 100644 --- a/tests/unit/test_db_fetch_page.py +++ b/tests/unit/test_db_fetch_page.py @@ -1,10 +1,9 @@ import pytest -import pytest_asyncio from tests.helpers import DbTestModel -@pytest_asyncio.fixture(scope="session") +@pytest.fixture(scope="session") async def fetch_page(db): await db.execute("DROP TABLE IF EXISTS test_db_fetch_page") await db.execute( @@ -30,7 +29,7 @@ async def fetch_page(db): await db.execute("DROP TABLE test_db_fetch_page") -@pytest.mark.asyncio +@pytest.mark.anyio async def test_db_fetch_page_simple(fetch_page, db): row = await db.fetch_page( query="select * from test_db_fetch_page", @@ -42,7 +41,7 @@ async def test_db_fetch_page_simple(fetch_page, db): assert len(row.data) == 5 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_db_fetch_page_group_by(fetch_page, db): row = await db.fetch_page( query="select max(id) as id, name from test_db_fetch_page", @@ -53,7 +52,7 @@ async def test_db_fetch_page_group_by(fetch_page, db): assert row.total == 4 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_db_fetch_page_group_by_multiple(fetch_page, db): row = await db.fetch_page( query="select max(id) as id, name, value from test_db_fetch_page", @@ -64,7 +63,7 @@ async def test_db_fetch_page_group_by_multiple(fetch_page, db): assert row.total == 5 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_db_fetch_page_group_by_evil(fetch_page, db): with pytest.raises(ValueError, match="Value for GROUP BY is invalid"): await db.fetch_page( diff --git a/tests/unit/test_helpers_query.py b/tests/unit/test_helpers_query.py index 81af0be6..5e2469f4 100644 --- a/tests/unit/test_helpers_query.py +++ b/tests/unit/test_helpers_query.py @@ -26,7 +26,7 @@ test_data = DbTestModel3( ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_helpers_insert_query(): q = insert_query("test_helpers_query", test_data) assert q == ( @@ -36,7 +36,7 @@ async def test_helpers_insert_query(): ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_helpers_update_query(): q = update_query("test_helpers_query", test_data) assert q == ( @@ -65,7 +65,7 @@ test_dict = { } -@pytest.mark.asyncio +@pytest.mark.anyio async def test_helpers_model_to_dict(): d = model_to_dict(test_data) assert d.get("id") == test_data.id @@ -75,7 +75,7 @@ async def test_helpers_model_to_dict(): assert d == test_dict -@pytest.mark.asyncio +@pytest.mark.anyio async def test_helpers_dict_to_model(): m = dict_to_model(test_dict, DbTestModel3) assert m == test_data diff --git a/tests/unit/test_pay_invoice.py b/tests/unit/test_pay_invoice.py index b28f6ccb..2776e65b 100644 --- a/tests/unit/test_pay_invoice.py +++ b/tests/unit/test_pay_invoice.py @@ -22,8 +22,8 @@ from lnbits.wallets.base import PaymentResponse from lnbits.wallets.fake import FakeWallet -@pytest.mark.asyncio -async def test_invalid_bolt11(to_wallet): +@pytest.mark.anyio +async def test_invalid_bolt11(to_wallet: Wallet): with pytest.raises(PaymentError): await pay_invoice( wallet_id=to_wallet.id, @@ -31,7 +31,7 @@ async def test_invalid_bolt11(to_wallet): ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_amountless_invoice(to_wallet: Wallet): zero_amount_invoice = ( "lnbc1pnsu5z3pp57getmdaxhg5kc9yh2a2qsh7cjf4gnccgkw0qenm8vsqv50w7s" @@ -47,7 +47,7 @@ async def test_amountless_invoice(to_wallet: Wallet): ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_bad_wallet_id(to_wallet: Wallet): payment = await create_invoice(wallet_id=to_wallet.id, amount=31, memo="Bad Wallet") bad_wallet_id = to_wallet.id[::-1] @@ -60,11 +60,10 @@ async def test_bad_wallet_id(to_wallet: Wallet): ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_payment_limit(to_wallet: Wallet): payment = await create_invoice(wallet_id=to_wallet.id, amount=101, memo="") with pytest.raises(PaymentError, match="Amount in invoice is too high."): - await pay_invoice( wallet_id=to_wallet.id, max_sat=100, @@ -72,7 +71,7 @@ async def test_payment_limit(to_wallet: Wallet): ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_twice(to_wallet: Wallet): payment = await create_invoice(wallet_id=to_wallet.id, amount=3, memo="Twice") await pay_invoice( @@ -86,7 +85,7 @@ async def test_pay_twice(to_wallet: Wallet): ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_fake_wallet_pay_external( to_wallet: Wallet, external_funding_source: FakeWallet ): @@ -101,7 +100,7 @@ async def test_fake_wallet_pay_external( ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_invoice_changed(to_wallet: Wallet): payment = await create_invoice(wallet_id=to_wallet.id, amount=21, memo="original") @@ -126,7 +125,7 @@ async def test_invoice_changed(to_wallet: Wallet): ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_for_extension(to_wallet: Wallet, settings: Settings): payment = await create_invoice(wallet_id=to_wallet.id, amount=3, memo="Allowed") await pay_invoice( @@ -144,7 +143,7 @@ async def test_pay_for_extension(to_wallet: Wallet, settings: Settings): ) -@pytest.mark.asyncio +@pytest.mark.anyio async def test_notification_for_internal_payment(to_wallet: Wallet): test_name = "test_notification_for_internal_payment" @@ -168,7 +167,7 @@ async def test_notification_for_internal_payment(to_wallet: Wallet): break # we found our payment, success -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_failed( to_wallet: Wallet, mocker: MockerFixture, external_funding_source: FakeWallet ): @@ -194,7 +193,7 @@ async def test_pay_failed( assert payment.amount == -2101_000 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_retry_failed_invoice( from_wallet: Wallet, mocker: MockerFixture, external_funding_source: FakeWallet ): @@ -264,7 +263,7 @@ async def test_retry_failed_invoice( assert ws_notification.call_count == 0, "Websocket notification not sent." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_external_invoice_pending( from_wallet: Wallet, mocker: MockerFixture, external_funding_source: FakeWallet ): @@ -310,7 +309,7 @@ async def test_pay_external_invoice_pending( assert ws_notification.call_count == 0, "Websocket notification not sent." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_retry_pay_external_invoice_pending( from_wallet: Wallet, mocker: MockerFixture, external_funding_source: FakeWallet ): @@ -355,7 +354,7 @@ async def test_retry_pay_external_invoice_pending( assert ws_notification.call_count == 0, "Websocket notification not sent." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_external_invoice_success( from_wallet: Wallet, mocker: MockerFixture, external_funding_source: FakeWallet ): @@ -401,7 +400,7 @@ async def test_pay_external_invoice_success( assert ws_notification.call_count == 1, "Websocket notification sent." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_retry_pay_success( from_wallet: Wallet, mocker: MockerFixture, external_funding_source: FakeWallet ): @@ -446,7 +445,7 @@ async def test_retry_pay_success( assert ws_notification.call_count == 1, "No new websocket notification sent." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_external_invoice_success_bad_checking_id( from_wallet: Wallet, mocker: MockerFixture, external_funding_source: FakeWallet ): @@ -479,7 +478,7 @@ async def test_pay_external_invoice_success_bad_checking_id( assert payment.status == PaymentState.SUCCESS.value -@pytest.mark.asyncio +@pytest.mark.anyio async def test_no_checking_id( from_wallet: Wallet, mocker: MockerFixture, external_funding_source: FakeWallet ): @@ -512,7 +511,7 @@ async def test_no_checking_id( assert payment.status == PaymentState.PENDING.value -@pytest.mark.asyncio +@pytest.mark.anyio async def test_service_fee( from_wallet: Wallet, to_wallet: Wallet, @@ -552,7 +551,7 @@ async def test_service_fee( assert _payment.preimage == preimage service_fee_payment = await get_standalone_payment( - f"service_fee_{payment.payment_hash}" + f"service_fee_{payment.payment_hash}", ) assert service_fee_payment assert service_fee_payment.status == PaymentState.SUCCESS.value diff --git a/tests/unit/test_services_fees.py b/tests/unit/test_services_fees.py index a7b0c2f3..c4163f44 100644 --- a/tests/unit/test_services_fees.py +++ b/tests/unit/test_services_fees.py @@ -7,13 +7,13 @@ from lnbits.core.services import ( from lnbits.settings import Settings -@pytest.mark.asyncio +@pytest.mark.anyio async def test_fee_reserve_internal(settings: Settings): fee = settings.fee_reserve(10_000, internal=True) assert fee == 0 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_fee_reserve_min(settings: Settings): settings.lnbits_reserve_fee_percent = 2 settings.lnbits_reserve_fee_min = 500 @@ -21,7 +21,7 @@ async def test_fee_reserve_min(settings: Settings): assert fee == 500 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_fee_reserve_percent(settings: Settings): settings.lnbits_reserve_fee_percent = 1 settings.lnbits_reserve_fee_min = 100 @@ -29,14 +29,14 @@ async def test_fee_reserve_percent(settings: Settings): assert fee == 1000 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_service_fee_no_wallet(settings: Settings): settings.lnbits_service_fee_wallet = "" fee = service_fee(10000) assert fee == 0 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_service_fee_internal(settings: Settings): settings.lnbits_service_fee_wallet = "wallet_id" settings.lnbits_service_fee_ignore_internal = True @@ -44,7 +44,7 @@ async def test_service_fee_internal(settings: Settings): assert fee == 0 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_service_fee(settings: Settings): settings.lnbits_service_fee_wallet = "wallet_id" settings.lnbits_service_fee = 2 @@ -52,7 +52,7 @@ async def test_service_fee(settings: Settings): assert fee == 200 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_service_fee_max(settings: Settings): settings.lnbits_service_fee_wallet = "wallet_id" settings.lnbits_service_fee = 2 @@ -61,7 +61,7 @@ async def test_service_fee_max(settings: Settings): assert fee / 1000 == 199 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_fee_reserve_total(settings: Settings): settings.lnbits_reserve_fee_percent = 1 settings.lnbits_reserve_fee_min = 100 diff --git a/tests/unit/test_services_wallet_limit.py b/tests/unit/test_services_wallet_limit.py index f3a64b6b..9cbc1fcb 100644 --- a/tests/unit/test_services_wallet_limit.py +++ b/tests/unit/test_services_wallet_limit.py @@ -4,7 +4,7 @@ from lnbits.core.services.payments import check_wallet_daily_withdraw_limit from lnbits.settings import Settings -@pytest.mark.asyncio +@pytest.mark.anyio async def test_no_wallet_limit(settings: Settings): settings.lnbits_wallet_limit_daily_max_withdraw = 0 result = await check_wallet_daily_withdraw_limit( @@ -14,7 +14,7 @@ async def test_no_wallet_limit(settings: Settings): assert result is None, "No limit set." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_wallet_limit_but_no_payments(settings: Settings): settings.lnbits_wallet_limit_daily_max_withdraw = 5 result = await check_wallet_daily_withdraw_limit( @@ -24,7 +24,7 @@ async def test_wallet_limit_but_no_payments(settings: Settings): assert result is None, "Limit not reqached." -@pytest.mark.asyncio +@pytest.mark.anyio async def test_no_wallet_spend_allowed(settings: Settings): settings.lnbits_wallet_limit_daily_max_withdraw = -1 diff --git a/tests/wallets/test_blink.py b/tests/wallets/test_blink.py index b35bd8b8..b07271a7 100644 --- a/tests/wallets/test_blink.py +++ b/tests/wallets/test_blink.py @@ -47,7 +47,7 @@ def outbound_bolt11(): return bolt11 -@pytest.mark.asyncio +@pytest.mark.anyio async def test_environment_variables(): if use_real_api: assert "X-API-KEY" in headers, "X-API-KEY is not present in headers" @@ -56,7 +56,7 @@ async def test_environment_variables(): assert True, "BLINK_TOKEN is not set. Skipping test using mock api" -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_wallet_id(): if use_real_api: wallet_id = await funding_source._init_wallet_id() @@ -66,7 +66,7 @@ async def test_get_wallet_id(): assert True, "BLINK_TOKEN is not set. Skipping test using mock api" -@pytest.mark.asyncio +@pytest.mark.anyio async def test_status(): if use_real_api: status = await funding_source.status() @@ -76,7 +76,7 @@ async def test_status(): assert True, "BLINK_TOKEN is not set. Skipping test using mock api" -@pytest.mark.asyncio +@pytest.mark.anyio async def test_create_invoice(): if use_real_api: invoice_response = await funding_source.create_invoice(amount=1000, memo="test") @@ -107,7 +107,7 @@ async def test_create_invoice(): assert True, "BLINK_TOKEN is not set. Skipping test using mock api" -@pytest.mark.asyncio +@pytest.mark.anyio async def test_pay_invoice_self_payment(): if use_real_api: invoice_response = await funding_source.create_invoice(amount=100, memo="test") @@ -122,7 +122,7 @@ async def test_pay_invoice_self_payment(): assert True, "BLINK_TOKEN is not set. Skipping test using mock api" -@pytest.mark.asyncio +@pytest.mark.anyio async def test_outbound_invoice_payment(outbound_bolt11): if use_real_api: payment_response = await funding_source.pay_invoice( @@ -138,7 +138,7 @@ async def test_outbound_invoice_payment(outbound_bolt11): assert True, "BLINK_TOKEN is not set. Skipping test using mock api" -@pytest.mark.asyncio +@pytest.mark.anyio async def test_get_payment_status(payhash): if use_real_api: payment_status = await funding_source.get_payment_status(payhash) diff --git a/tests/wallets/test_nwc_wallets.py b/tests/wallets/test_nwc_wallets.py index 1b9793c1..624cc580 100644 --- a/tests/wallets/test_nwc_wallets.py +++ b/tests/wallets/test_nwc_wallets.py @@ -174,7 +174,7 @@ async def run(data: WalletTest): await nwcwallet.cleanup() -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.parametrize( "test_data", wallet_fixtures_from_json("tests/wallets/fixtures/json/fixtures_nwc.json"), @@ -184,7 +184,7 @@ async def test_nwc_wallet(test_data: WalletTest): await run(test_data) -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.parametrize( "test_data", wallet_fixtures_from_json("tests/wallets/fixtures/json/fixtures_nwc_bad.json"), diff --git a/tests/wallets/test_rest_wallets.py b/tests/wallets/test_rest_wallets.py index 930bb80d..ddd4a62b 100644 --- a/tests/wallets/test_rest_wallets.py +++ b/tests/wallets/test_rest_wallets.py @@ -28,7 +28,7 @@ def httpserver_listen_address(): return ("127.0.0.1", 8555) -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.parametrize( "test_data", wallet_fixtures_from_json("tests/wallets/fixtures/json/fixtures_rest.json"), diff --git a/tests/wallets/test_rpc_wallets.py b/tests/wallets/test_rpc_wallets.py index 556ebabb..6bd68f40 100644 --- a/tests/wallets/test_rpc_wallets.py +++ b/tests/wallets/test_rpc_wallets.py @@ -18,7 +18,7 @@ from tests.wallets.helpers import ( ) -@pytest.mark.asyncio +@pytest.mark.anyio @pytest.mark.parametrize( "test_data", wallet_fixtures_from_json("tests/wallets/fixtures/json/fixtures_rpc.json"),