Skip to content

Commit 0523724

Browse files
author
Review
committed
test: update tests for async-only API
- Convert test conftest to async (fixtures, setup/teardown) - Remove 174 sync test functions (duplicates of async tests) - Convert unique sync-only tests to async - Skip CalDAV tests (not available in async-only mode) - Convert test entry scripts (_install.py, _talk_bot.py, etc.) - Update README to reflect async-only API
1 parent cc9c832 commit 0523724

32 files changed

Lines changed: 243 additions & 2196 deletions

README.md

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,11 @@ Python library that provides a robust and well-documented API that allows develo
1717
* **Reliable**: Minimum number of incompatible changes.
1818
* **Robust**: All code is covered with tests as much as possible.
1919
* **Easy**: Designed to be easy to use.
20-
* **Async-first**: Full async API with sync wrappers available for most modules.
21-
22-
### Deprecation notice: sync API
23-
24-
Starting with version **0.30.0**, we are gradually removing sync wrappers in favour of
25-
the async API. The following modules have already lost their sync counterparts:
26-
**Activity**, **Notes**, **User Status**, and **Weather Status**.
27-
28-
All remaining sync methods will be phased out in future releases. If you are still
29-
using the sync `Nextcloud` / `NextcloudApp` classes, we recommend migrating to
30-
`AsyncNextcloud` / `AsyncNextcloudApp` as soon as possible.
20+
* **Async**: Fully async API built on top of `niquests`.
3121

3222
### Differences between the Nextcloud and NextcloudApp classes
3323

34-
The **Nextcloud** class functions as a standard Nextcloud client,
24+
The **Nextcloud** class functions as a standard async Nextcloud client,
3525
enabling you to make API requests using a username and password.
3626

3727
On the other hand, the **NextcloudApp** class is designed for creating applications for Nextcloud.<br>
@@ -52,7 +42,7 @@ from contextlib import asynccontextmanager
5242

5343
from fastapi import FastAPI
5444

55-
from nc_py_api import AsyncNextcloudApp
45+
from nc_py_api import NextcloudApp
5646
from nc_py_api.ex_app import AppAPIAuthMiddleware, LogLvl, run_app, set_handlers
5747

5848

@@ -66,7 +56,7 @@ APP = FastAPI(lifespan=lifespan)
6656
APP.add_middleware(AppAPIAuthMiddleware)
6757

6858

69-
async def enabled_handler(enabled: bool, nc: AsyncNextcloudApp) -> str:
59+
async def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
7060
if enabled:
7161
await nc.log(LogLvl.WARNING, "Hello from nc_py_api.")
7262
else:

tests/_install.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,33 @@ async def lifespan(_app: FastAPI):
1717

1818

1919
@APP.put("/sec_check")
20-
def sec_check(
20+
async def sec_check(
2121
value: int,
2222
_nc: typing.Annotated[NextcloudApp, Depends(ex_app.nc_app)],
2323
):
2424
print(value, flush=True)
2525
return JSONResponse(content={"error": ""}, status_code=200)
2626

2727

28-
def init_handler_background(nc: NextcloudApp):
29-
nc.set_init_status(100)
28+
async def init_handler_background(nc: NextcloudApp):
29+
await nc.set_init_status(100)
3030

3131

3232
@APP.post("/init")
33-
def init_handler(
33+
async def init_handler(
3434
background_tasks: BackgroundTasks,
3535
nc: typing.Annotated[NextcloudApp, Depends(ex_app.nc_app)],
3636
):
3737
background_tasks.add_task(init_handler_background, nc)
3838
return JSONResponse(content={}, status_code=200)
3939

4040

41-
def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
41+
async def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
4242
print(f"enabled_handler: enabled={enabled}", flush=True)
4343
if enabled:
44-
nc.log(ex_app.LogLvl.WARNING, f"Hello from {nc.app_cfg.app_name} :)")
44+
await nc.log(ex_app.LogLvl.WARNING, f"Hello from {nc.app_cfg.app_name} :)")
4545
else:
46-
nc.log(ex_app.LogLvl.WARNING, f"Bye bye from {nc.app_cfg.app_name} :(")
46+
await nc.log(ex_app.LogLvl.WARNING, f"Bye bye from {nc.app_cfg.app_name} :(")
4747
return ""
4848

4949

tests/_install_init_handler_models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ async def lifespan(_app: FastAPI):
2828
APP = FastAPI(lifespan=lifespan)
2929

3030

31-
def enabled_handler(enabled: bool, _nc: NextcloudApp) -> str:
31+
async def enabled_handler(enabled: bool, _nc: NextcloudApp) -> str:
3232
if enabled:
3333
assert ex_app.get_model_path(MODEL_NAME2)
3434
assert Path("pytorch_model.bin").is_file()

tests/_install_only_enabled_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ async def lifespan(_app: FastAPI):
1414
APP = FastAPI(lifespan=lifespan)
1515

1616

17-
def enabled_handler(_enabled: bool, _nc: NextcloudApp) -> str:
17+
async def enabled_handler(_enabled: bool, _nc: NextcloudApp) -> str:
1818
return ""
1919

2020

tests/_talk_bot.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
COVERAGE_BOT = talk_bot.TalkBot("/talk_bot_coverage", "Coverage bot", "Desc")
1414

1515

16-
def coverage_talk_bot_process_request(message: talk_bot.TalkBotMessage, request: Request):
16+
async def coverage_talk_bot_process_request(message: talk_bot.TalkBotMessage, request: Request):
1717
if message.object_name != "message":
1818
return
19-
COVERAGE_BOT.react_to_message(message, "🥳")
20-
COVERAGE_BOT.react_to_message(message, "🫡")
21-
COVERAGE_BOT.delete_reaction(message, "🫡")
22-
COVERAGE_BOT.send_message("Hello from bot!", message)
19+
await COVERAGE_BOT.react_to_message(message, "🥳")
20+
await COVERAGE_BOT.react_to_message(message, "🫡")
21+
await COVERAGE_BOT.delete_reaction(message, "🫡")
22+
await COVERAGE_BOT.send_message("Hello from bot!", message)
2323
assert isinstance(message.actor_id, str)
2424
assert isinstance(message.actor_display_name, str)
2525
assert isinstance(message.object_name, str)
@@ -28,15 +28,15 @@ def coverage_talk_bot_process_request(message: talk_bot.TalkBotMessage, request:
2828
assert isinstance(message.conversation_name, str)
2929
assert str(message).find("conversation=") != -1
3030
with pytest.raises(ValueError):
31-
COVERAGE_BOT.react_to_message(message.object_id, "🥳")
31+
await COVERAGE_BOT.react_to_message(message.object_id, "🥳")
3232
with pytest.raises(ValueError):
33-
COVERAGE_BOT.delete_reaction(message.object_id, "🥳")
33+
await COVERAGE_BOT.delete_reaction(message.object_id, "🥳")
3434
with pytest.raises(ValueError):
35-
COVERAGE_BOT.send_message("🥳", message.object_id)
35+
await COVERAGE_BOT.send_message("🥳", message.object_id)
3636

3737

3838
@APP.post("/talk_bot_coverage")
39-
def talk_bot_coverage(
39+
async def talk_bot_coverage(
4040
request: Request,
4141
_nc: Annotated[NextcloudApp, Depends(nc_app)],
4242
message: Annotated[talk_bot.TalkBotMessage, Depends(talk_bot_msg)],
@@ -48,7 +48,7 @@ def talk_bot_coverage(
4848

4949
# in real program this is not needed, as bot enabling handler is called in the bots process itself and will reset it.
5050
@APP.delete("/reset_bot_secret")
51-
def reset_bot_secret():
51+
async def reset_bot_secret():
5252
os.environ.pop(talk_bot.__get_bot_secret("/talk_bot_coverage"), None)
5353
return Response()
5454

tests/_tests_at_the_end.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,23 @@ def _test_ex_app_enable_disable(file_to_test):
2222

2323

2424
@pytest.mark.parametrize("file_to_test", ("_install_only_enabled_handler.py", "_install_only_enabled_handler_async.py"))
25-
def test_ex_app_enable_disable(nc_client, nc_app, file_to_test):
25+
async def test_ex_app_enable_disable(nc_client, nc_app, file_to_test):
2626
r, url = _test_ex_app_enable_disable(file_to_test)
2727
try:
2828
if check_heartbeat(url, '"status":"ok"', 15, 0.3):
2929
raise RuntimeError(f"`{file_to_test}` can not start.")
30-
if nc_client.apps.ex_app_is_enabled("nc_py_api"):
31-
nc_client.apps.ex_app_disable("nc_py_api")
32-
assert nc_client.apps.ex_app_is_disabled("nc_py_api") is True
33-
assert nc_client.apps.ex_app_is_enabled("nc_py_api") is False
34-
nc_client.apps.ex_app_enable("nc_py_api")
35-
assert nc_client.apps.ex_app_is_disabled("nc_py_api") is False
36-
assert nc_client.apps.ex_app_is_enabled("nc_py_api") is True
30+
if await nc_client.apps.ex_app_is_enabled("nc_py_api"):
31+
await nc_client.apps.ex_app_disable("nc_py_api")
32+
assert await nc_client.apps.ex_app_is_disabled("nc_py_api") is True
33+
assert await nc_client.apps.ex_app_is_enabled("nc_py_api") is False
34+
await nc_client.apps.ex_app_enable("nc_py_api")
35+
assert await nc_client.apps.ex_app_is_disabled("nc_py_api") is False
36+
assert await nc_client.apps.ex_app_is_enabled("nc_py_api") is True
3737
finally:
3838
r.terminate()
3939
r.wait(timeout=10)
4040

4141

42-
@pytest.mark.asyncio(scope="session")
4342
@pytest.mark.parametrize("file_to_test", ("_install_only_enabled_handler.py", "_install_only_enabled_handler_async.py"))
4443
async def test_ex_app_enable_disable_async(anc_client, anc_app, file_to_test):
4544
r, url = _test_ex_app_enable_disable(file_to_test)

0 commit comments

Comments
 (0)