Skip to content

Commit 5ee9435

Browse files
committed
test: Update tests with async
1 parent 110df3d commit 5ee9435

File tree

7 files changed

+116
-113
lines changed

7 files changed

+116
-113
lines changed

nextcloud_mcp_server/client.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
Request,
99
Response,
1010
HTTPStatusError,
11-
) # Import HTTPStatusError
11+
)
1212
import logging
1313

1414

@@ -172,16 +172,16 @@ async def notes_update_note(
172172
async def notes_append_content(self, *, note_id: int, content: str):
173173
"""Append content to an existing note.
174174
175-
The content will be separated by a newline, delimiter `---`, and
176-
timestemp so callers do not need to append metadata themselves.
175+
The content will be separated by a newline and a delimiter `---`, so
176+
one will not be required in the content provided to this tool
177177
"""
178178
logger.info(f"Appending content to note {note_id}")
179179

180180
# Get current note
181181
current_note = await self.notes_get_note(note_id=note_id)
182182

183183
# Use fixed separator for consistency
184-
separator = f"\n---\n## Content appended: {dt.datetime.now():%Y-%m-%d %H:%M}\n"
184+
separator = f"\n---\n"
185185

186186
# Combine content
187187
existing_content = current_note.get("content", "")

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ nc-mcp-server = "nextcloud_mcp_server.server:run"
1818

1919
[tool.pytest.ini_options]
2020
asyncio_mode = "auto"
21+
asyncio_default_test_loop_scope = "session"
22+
asyncio_default_fixture_loop_scope = "session"
2123
log_cli = 1
2224
log_cli_level = "WARN"
2325
log_level = "WARN"

tests/conftest.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,21 @@
33
import logging
44
import uuid
55
from nextcloud_mcp_server.client import NextcloudClient, HTTPStatusError
6+
import asyncio
7+
import pytest_asyncio
68

79
logger = logging.getLogger(__name__)
810

11+
# pytestmark = pytest.mark.asyncio(loop_scope="package")
12+
913

1014
@pytest.fixture(scope="session")
1115
async def nc_client() -> NextcloudClient:
1216
"""
1317
Fixture to create a NextcloudClient instance for integration tests.
1418
Uses environment variables for configuration.
1519
"""
20+
1621
assert os.getenv("NEXTCLOUD_HOST"), "NEXTCLOUD_HOST env var not set"
1722
assert os.getenv("NEXTCLOUD_USERNAME"), "NEXTCLOUD_USERNAME env var not set"
1823
assert os.getenv("NEXTCLOUD_PASSWORD"), "NEXTCLOUD_PASSWORD env var not set"
@@ -36,6 +41,8 @@ async def temporary_note(nc_client: NextcloudClient):
3641
Fixture to create a temporary note for a test and ensure its deletion afterward.
3742
Yields the created note dictionary.
3843
"""
44+
asyncio.new_event_loop()
45+
3946
note_id = None
4047
unique_suffix = uuid.uuid4().hex[:8]
4148
note_title = f"Temporary Test Note {unique_suffix}"
@@ -80,6 +87,8 @@ async def temporary_note_with_attachment(
8087
Yields a tuple: (note_data, attachment_filename, attachment_content).
8188
Depends on the temporary_note fixture.
8289
"""
90+
asyncio.new_event_loop()
91+
8392
note_data = temporary_note
8493
note_id = note_data["id"]
8594
note_category = note_data.get("category") # Get category from the note data

tests/integration/test_attachments.py

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
pytestmark = pytest.mark.integration
1616

1717

18-
def test_attachments_add_and_get(
18+
async def test_attachments_add_and_get(
1919
nc_client: NextcloudClient, temporary_note_with_attachment: tuple
2020
):
2121
"""
@@ -29,7 +29,7 @@ def test_attachments_add_and_get(
2929
f"Attempting to retrieve attachment '{attachment_filename}' added by fixture for note ID: {note_id}"
3030
)
3131
# Pass category to get_note_attachment
32-
retrieved_content, retrieved_mime = nc_client.get_note_attachment(
32+
retrieved_content, retrieved_mime = await nc_client.get_note_attachment(
3333
note_id=note_id, filename=attachment_filename, category=note_category
3434
)
3535
logger.info(
@@ -41,7 +41,7 @@ def test_attachments_add_and_get(
4141
logger.info("Retrieved attachment content and mime type verified successfully.")
4242

4343

44-
def test_attachments_add_to_note_with_category(
44+
async def test_attachments_add_to_note_with_category(
4545
nc_client: NextcloudClient, temporary_note: dict
4646
):
4747
"""
@@ -67,7 +67,7 @@ def test_attachments_add_to_note_with_category(
6767
f"Attempting to add attachment '{attachment_filename}' to note ID: {note_id}"
6868
)
6969
# Pass category to add_note_attachment
70-
upload_response = nc_client.add_note_attachment(
70+
upload_response = await nc_client.add_note_attachment(
7171
note_id=note_id,
7272
filename=attachment_filename,
7373
content=attachment_content,
@@ -86,7 +86,7 @@ def test_attachments_add_to_note_with_category(
8686
f"Attempting to retrieve attachment '{attachment_filename}' from note ID: {note_id}"
8787
)
8888
# Pass category to get_note_attachment
89-
retrieved_content, retrieved_mime = nc_client.get_note_attachment(
89+
retrieved_content, retrieved_mime = await nc_client.get_note_attachment(
9090
note_id=note_id,
9191
filename=attachment_filename,
9292
category=note_category, # Pass the note's category
@@ -103,7 +103,7 @@ def test_attachments_add_to_note_with_category(
103103
# Cleanup is handled by the temporary_note fixture
104104

105105

106-
def test_attachments_cleanup_on_note_delete(
106+
async def test_attachments_cleanup_on_note_delete(
107107
nc_client: NextcloudClient, temporary_note_with_attachment: tuple
108108
):
109109
"""
@@ -127,13 +127,13 @@ def test_attachments_cleanup_on_note_delete(
127127

128128
# Manually delete the note
129129
logger.info(f"Manually deleting note ID: {note_id} within the test.")
130-
nc_client.notes_delete_note(note_id=note_id)
130+
await nc_client.notes_delete_note(note_id=note_id)
131131
logger.info(f"Note ID: {note_id} deleted successfully.")
132132
time.sleep(1)
133133

134134
# Verify Note Is Deleted
135135
with pytest.raises(HTTPStatusError) as excinfo_note:
136-
nc_client.notes_get_note(note_id=note_id)
136+
await nc_client.notes_get_note(note_id=note_id)
137137
assert excinfo_note.value.response.status_code == 404
138138
logger.info(f"Verified note {note_id} deletion (404 received).")
139139

@@ -145,7 +145,7 @@ def test_attachments_cleanup_on_note_delete(
145145
# Pass category to get_note_attachment - although it should fail anyway
146146
# because the note (and thus details) are gone.
147147
# The client method will raise 404 from the initial notes_get_note call.
148-
nc_client.get_note_attachment(
148+
await nc_client.get_note_attachment(
149149
note_id=note_id,
150150
filename=attachment_filename,
151151
category=note_category, # Pass category, though note fetch should fail first
@@ -165,21 +165,21 @@ def test_attachments_cleanup_on_note_delete(
165165
)
166166
propfind_headers = {"Depth": "0", "OCS-APIRequest": "true"}
167167
try:
168-
propfind_resp = nc_client._client.request(
168+
propfind_resp = await nc_client._client.request(
169169
"PROPFIND", attachment_dir_path, headers=propfind_headers
170170
)
171171
status = propfind_resp.status_code
172172
if status in [200, 207]: # Successful PROPFIND means directory exists
173173
logger.error(
174174
f"Attachment directory still exists! PROPFIND returned {status}"
175175
)
176-
assert False, (
177-
f"Expected attachment directory to be gone, but PROPFIND returned {status}!"
178-
)
176+
assert (
177+
False
178+
), f"Expected attachment directory to be gone, but PROPFIND returned {status}!"
179179
except HTTPStatusError as e:
180-
assert e.response.status_code == 404, (
181-
f"Expected PROPFIND to fail with 404, got {e.response.status_code}"
182-
)
180+
assert (
181+
e.response.status_code == 404
182+
), f"Expected PROPFIND to fail with 404, got {e.response.status_code}"
183183
logger.info(
184184
"Verified attachment directory does not exist via PROPFIND (404 received)"
185185
)
@@ -188,7 +188,7 @@ def test_attachments_cleanup_on_note_delete(
188188
# but it will find the note already deleted (404) and handle it gracefully.
189189

190190

191-
def test_attachments_category_change_handling(nc_client: NextcloudClient):
191+
async def test_attachments_category_change_handling(nc_client: NextcloudClient):
192192
"""
193193
Tests attachment handling when a note's category is changed.
194194
Verifies attachment retrieval works before and after category change,
@@ -205,7 +205,7 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
205205
try:
206206
# 1. Create note with initial category
207207
logger.info(f"Creating note '{note_title}' in category '{initial_category}'")
208-
created_note = nc_client.notes_create_note(
208+
created_note = await nc_client.notes_create_note(
209209
title=note_title, content="Initial content", category=initial_category
210210
)
211211
note_id = created_note["id"]
@@ -217,7 +217,7 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
217217
logger.info(
218218
f"Adding attachment '{attachment_filename}' to note {note_id} (in {initial_category})"
219219
)
220-
upload_response = nc_client.add_note_attachment(
220+
upload_response = await nc_client.add_note_attachment(
221221
note_id=note_id,
222222
filename=attachment_filename,
223223
content=attachment_content,
@@ -232,7 +232,7 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
232232
logger.info(
233233
f"Verifying attachment retrieval from initial category '{initial_category}'"
234234
)
235-
retrieved_content1, _ = nc_client.get_note_attachment(
235+
retrieved_content1, _ = await nc_client.get_note_attachment(
236236
note_id=note_id, filename=attachment_filename, category=initial_category
237237
)
238238
assert retrieved_content1 == attachment_content
@@ -243,9 +243,9 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
243243
f"Updating note {note_id} category from '{initial_category}' to '{new_category}'"
244244
)
245245
# Need to fetch the latest etag after attachment add (WebDAV ops don't update note etag)
246-
current_note_data = nc_client.notes_get_note(note_id=note_id)
246+
current_note_data = await nc_client.notes_get_note(note_id=note_id)
247247
current_etag = current_note_data["etag"]
248-
updated_note = nc_client.notes_update_note(
248+
updated_note = await nc_client.notes_update_note(
249249
note_id=note_id,
250250
etag=current_etag,
251251
category=new_category,
@@ -261,7 +261,7 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
261261
logger.info(
262262
f"Verifying attachment retrieval from new category '{new_category}'"
263263
)
264-
retrieved_content2, _ = nc_client.get_note_attachment(
264+
retrieved_content2, _ = await nc_client.get_note_attachment(
265265
note_id=note_id, filename=attachment_filename, category=new_category
266266
)
267267
assert retrieved_content2 == attachment_content
@@ -275,21 +275,21 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
275275
)
276276
propfind_headers = {"Depth": "0", "OCS-APIRequest": "true"}
277277
try:
278-
propfind_resp = nc_client._client.request(
278+
propfind_resp = await nc_client._client.request(
279279
"PROPFIND", old_attachment_dir_path, headers=propfind_headers
280280
)
281281
status = propfind_resp.status_code
282282
if status in [200, 207]: # Successful PROPFIND means directory exists
283283
logger.error(
284284
f"Old attachment directory still exists! PROPFIND returned {status}"
285285
)
286-
assert False, (
287-
f"Expected old directory to be gone, but PROPFIND returned {status} - directory still exists!"
288-
)
286+
assert (
287+
False
288+
), f"Expected old directory to be gone, but PROPFIND returned {status} - directory still exists!"
289289
except HTTPStatusError as e:
290-
assert e.response.status_code == 404, (
291-
f"Expected PROPFIND to fail with 404, got {e.response.status_code}"
292-
)
290+
assert (
291+
e.response.status_code == 404
292+
), f"Expected PROPFIND to fail with 404, got {e.response.status_code}"
293293
logger.info(
294294
"Verified old attachment directory does not exist via PROPFIND (404 received)"
295295
)
@@ -300,7 +300,7 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
300300
f"{webdav_base}/Notes/{new_category}/.attachments.{note_id}"
301301
)
302302
try:
303-
propfind_resp = nc_client._client.request(
303+
propfind_resp = await nc_client._client.request(
304304
"PROPFIND", new_attachment_dir_path, headers=propfind_headers
305305
)
306306
status = propfind_resp.status_code
@@ -315,9 +315,9 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
315315
logger.error(
316316
f"New attachment directory not found! PROPFIND failed with {e.response.status_code}"
317317
)
318-
assert False, (
319-
f"Expected new attachment directory to exist, but PROPFIND failed with {e.response.status_code}"
320-
)
318+
assert (
319+
False
320+
), f"Expected new attachment directory to exist, but PROPFIND failed with {e.response.status_code}"
321321

322322
finally:
323323
# 6. Cleanup: Delete the note (client should use the *final* category for cleanup path)
@@ -326,18 +326,18 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
326326
f"Cleaning up note ID: {note_id} (last known category: '{new_category}')"
327327
)
328328
try:
329-
nc_client.notes_delete_note(note_id=note_id)
329+
await nc_client.notes_delete_note(note_id=note_id)
330330
logger.info(f"Note {note_id} deleted.")
331331
time.sleep(1)
332332
# Verify note deletion
333333
with pytest.raises(HTTPStatusError) as excinfo_note_del:
334-
nc_client.notes_get_note(note_id=note_id)
334+
await nc_client.notes_get_note(note_id=note_id)
335335
assert excinfo_note_del.value.response.status_code == 404
336336
logger.info("Verified note deleted (404).")
337337
# Verify attachment deletion (should fail with 404 on the initial note fetch)
338338
with pytest.raises(HTTPStatusError) as excinfo_attach_del:
339339
# Pass the *last known* category, although the note fetch should fail first
340-
nc_client.get_note_attachment(
340+
await nc_client.get_note_attachment(
341341
note_id=note_id,
342342
filename=attachment_filename,
343343
category=new_category,
@@ -359,7 +359,7 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
359359
)
360360
propfind_headers = {"Depth": "0", "OCS-APIRequest": "true"}
361361
try:
362-
resp = nc_client._client.request(
362+
resp = await nc_client._client.request(
363363
"PROPFIND", new_attachment_dir_path, headers=propfind_headers
364364
)
365365
if resp.status_code in [
@@ -368,9 +368,9 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
368368
]: # Successful PROPFIND means directory exists
369369
assert False, "New category attachment directory still exists!"
370370
except HTTPStatusError as e:
371-
assert e.response.status_code == 404, (
372-
f"Expected PROPFIND to fail with 404, got {e.response.status_code}"
373-
)
371+
assert (
372+
e.response.status_code == 404
373+
), f"Expected PROPFIND to fail with 404, got {e.response.status_code}"
374374
logger.info(
375375
"Verified new category attachment directory is gone via PROPFIND"
376376
)
@@ -380,7 +380,7 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
380380
f"{webdav_base}/Notes/{initial_category}/.attachments.{note_id}"
381381
)
382382
try:
383-
resp = nc_client._client.request(
383+
resp = await nc_client._client.request(
384384
"PROPFIND", old_attachment_dir_path, headers=propfind_headers
385385
)
386386
if resp.status_code in [
@@ -389,9 +389,9 @@ def test_attachments_category_change_handling(nc_client: NextcloudClient):
389389
]: # Successful PROPFIND means directory exists
390390
assert False, "Old category attachment directory still exists!"
391391
except HTTPStatusError as e:
392-
assert e.response.status_code == 404, (
393-
f"Expected PROPFIND to fail with 404, got {e.response.status_code}"
394-
)
392+
assert (
393+
e.response.status_code == 404
394+
), f"Expected PROPFIND to fail with 404, got {e.response.status_code}"
395395
logger.info(
396396
"Verified old category attachment directory is gone via PROPFIND"
397397
)

0 commit comments

Comments
 (0)