Skip to main content
Glama
cbcoutinho

Nextcloud MCP Server

by cbcoutinho
test_webdav_cleanup.py12.1 kB
import logging import time import uuid import pytest from httpx import HTTPStatusError from nextcloud_mcp_server.client import NextcloudClient logger = logging.getLogger(__name__) # Mark all tests in this module as integration tests pytestmark = pytest.mark.integration async def test_category_change_cleans_up_old_attachments_directory( nc_client: NextcloudClient, ): """ Tests that when a note's category is changed, the old attachment directory is properly cleaned up. """ note_id = None initial_category = "CategoryTest1" new_category = "CategoryTest2" unique_suffix = uuid.uuid4().hex[:8] note_title = f"Category Cleanup Test {unique_suffix}" attachment_filename = f"cleanup_test_{unique_suffix}.txt" attachment_content = f"Content for {attachment_filename}".encode("utf-8") try: # 1. Create note with initial category logger.info(f"Creating note '{note_title}' in category '{initial_category}'") created_note = await nc_client.notes.create_note( title=note_title, content="Initial content", category=initial_category ) note_id = created_note["id"] etag1 = created_note["etag"] logger.info(f"Note created with ID: {note_id}, Etag: {etag1}") time.sleep(1) # 2. Add attachment (passing initial category) logger.info( f"Adding attachment '{attachment_filename}' to note {note_id} (in {initial_category})" ) upload_response = await nc_client.webdav.add_note_attachment( note_id=note_id, filename=attachment_filename, content=attachment_content, category=initial_category, mime_type="text/plain", ) assert upload_response["status_code"] in [201, 204] logger.info("Attachment added successfully.") time.sleep(1) # 3. Verify attachment retrieval from initial category logger.info( f"Verifying attachment retrieval from initial category '{initial_category}'" ) retrieved_content1, _ = await nc_client.webdav.get_note_attachment( note_id=note_id, filename=attachment_filename, category=initial_category ) assert retrieved_content1 == attachment_content logger.info("Attachment retrieved successfully from initial category.") # 4. Construct and check the WebDAV path for the initial category's attachment directory initial_webdav_path = f"Notes/{initial_category}/.attachments.{note_id}" logger.info(f"Initial WebDAV path for attachments: {initial_webdav_path}") # Here we would check if the directory exists, but the WebDAV client doesn't directly # expose directory listing functionality, so we'll infer from attachment retrieval success # 5. Update note category logger.info( f"Updating note {note_id} category from '{initial_category}' to '{new_category}'" ) current_note_data = await nc_client.notes.get_note(note_id=note_id) current_etag = current_note_data["etag"] updated_note = await nc_client.notes.update( note_id=note_id, etag=current_etag, category=new_category, title=note_title, content="Updated content", ) etag3 = updated_note["etag"] assert updated_note["category"] == new_category logger.info(f"Note category updated successfully. New Etag: {etag3}") time.sleep(1) # 6. Verify attachment retrieval from new category logger.info( f"Verifying attachment retrieval from new category '{new_category}'" ) retrieved_content2, _ = await nc_client.webdav.get_note_attachment( note_id=note_id, filename=attachment_filename, category=new_category ) assert retrieved_content2 == attachment_content logger.info("Attachment retrieved successfully from new category.") # 7. Try to retrieve from old category - this should fail logger.info( f"Trying to retrieve attachment from old category '{initial_category}' - should fail" ) try: await nc_client.webdav.get_note_attachment( note_id=note_id, filename=attachment_filename, category=initial_category ) # If we get here, it means the old directory still exists (a problem) logger.error( "ISSUE DETECTED: Was able to retrieve attachment from old category path!" ) assert False, ( "Old category attachment directory still exists and accessible!" ) except HTTPStatusError as e: # This is the expected outcome - old directory should be gone logger.info( f"Correctly got error accessing old category path: {e.response.status_code}" ) assert e.response.status_code == 404, ( f"Expected 404, got {e.response.status_code}" ) logger.info( "Verified old category attachment directory is not accessible (good!)" ) # 7.1 Directly check old attachment directory existence using WebDAV PROPFIND logger.info( "Directly checking if old attachment directory exists in WebDAV" ) webdav_base = nc_client._get_webdav_base_path() old_attachment_dir_path = ( f"{webdav_base}/Notes/{initial_category}/.attachments.{note_id}" ) propfind_headers = {"Depth": "0", "OCS-APIRequest": "true"} try: propfind_resp = await nc_client._client.request( "PROPFIND", old_attachment_dir_path, headers=propfind_headers ) status = propfind_resp.status_code if status in [ 200, 207, ]: # Success codes indicate the directory exists (a problem) logger.error( f"Old attachment directory still exists! PROPFIND returned {status}" ) assert False, ( f"Expected old attachment directory to be gone, but it still exists (PROPFIND returned {status})!" ) # If we got another status code (like 404), it's also good - the directory doesn't exist logger.info( f"Verified old attachment directory does not exist (PROPFIND returned {status})" ) except HTTPStatusError as e: # 404 is expected - directory should not exist assert e.response.status_code == 404, ( f"Expected PROPFIND to fail with 404, got {e.response.status_code}" ) logger.info( "Verified old attachment directory does not exist via PROPFIND (404 received)" ) finally: # 8. Cleanup: Delete the note if note_id: logger.info(f"Cleaning up note ID: {note_id}") try: await nc_client.notes.delete_note(note_id=note_id) logger.info(f"Note {note_id} deleted.") time.sleep(1) # 9. Verify both old and new attachment paths are gone logger.info("Verifying all attachment paths are gone") with pytest.raises(HTTPStatusError) as excinfo_new: await nc_client.webdav.get_note_attachment( note_id=note_id, filename=attachment_filename, category=new_category, ) assert excinfo_new.value.response.status_code == 404 with pytest.raises(HTTPStatusError) as excinfo_old: await nc_client.webdav.get_note_attachment( note_id=note_id, filename=attachment_filename, category=initial_category, ) assert excinfo_old.value.response.status_code == 404 # 9.1 Directly verify directories don't exist using WebDAV PROPFIND logger.info( "Directly verifying attachment directories don't exist via PROPFIND" ) webdav_base = nc_client._get_webdav_base_path() # Check new category attachment directory new_attachment_dir_path = ( f"{webdav_base}/Notes/{new_category}/.attachments.{note_id}" ) propfind_headers = {"Depth": "0", "OCS-APIRequest": "true"} try: propfind_resp = await nc_client._client.request( "PROPFIND", new_attachment_dir_path, headers=propfind_headers ) status = propfind_resp.status_code if status in [ 200, 207, ]: # Success codes indicate the directory exists (a problem) logger.error( f"New category attachment directory still exists! PROPFIND returned {status}" ) assert False, ( f"Expected new category attachment directory to be gone, but it still exists (PROPFIND returned {status})!" ) # If we got another status code (like 404), it's also good - the directory doesn't exist logger.info( f"Verified new category attachment directory does not exist (PROPFIND returned {status})" ) except HTTPStatusError as e: assert e.response.status_code == 404, ( f"Expected PROPFIND to fail with 404, got {e.response.status_code}" ) logger.info( "Verified new category attachment directory is gone via PROPFIND" ) # Check old category attachment directory old_attachment_dir_path = ( f"{webdav_base}/Notes/{initial_category}/.attachments.{note_id}" ) try: propfind_resp = await nc_client._client.request( "PROPFIND", old_attachment_dir_path, headers=propfind_headers ) status = propfind_resp.status_code if status in [ 200, 207, ]: # Success codes indicate the directory exists (a problem) logger.error( f"Old category attachment directory still exists! PROPFIND returned {status}" ) assert False, ( f"Expected old category attachment directory to be gone, but it still exists (PROPFIND returned {status})!" ) # If we got another status code (like 404), it's also good - the directory doesn't exist logger.info( f"Verified old category attachment directory does not exist (PROPFIND returned {status})" ) except HTTPStatusError as e: assert e.response.status_code == 404, ( f"Expected PROPFIND to fail with 404, got {e.response.status_code}" ) logger.info( "Verified old category attachment directory is gone via PROPFIND" ) logger.info( "Verified all attachment directories are properly cleaned up." ) except Exception as e: logger.error(f"Error during cleanup for note {note_id}: {e}")

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cbcoutinho/nextcloud-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server