118 lines
5.3 KiB
Python
118 lines
5.3 KiB
Python
import pytest
|
|
import logging
|
|
import time
|
|
import uuid
|
|
from httpx import HTTPStatusError
|
|
|
|
from nextcloud_mcp_server.client import NextcloudClient
|
|
|
|
# Note: nc_client fixture is session-scoped in conftest.py
|
|
# Note: temporary_note and temporary_note_with_attachment fixtures are function-scoped in conftest.py
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Mark all tests in this module as integration tests
|
|
pytestmark = pytest.mark.integration
|
|
|
|
def test_attachments_add_and_get(nc_client: NextcloudClient, temporary_note_with_attachment: tuple):
|
|
"""
|
|
Tests adding an attachment (via fixture) and retrieving it.
|
|
"""
|
|
note_data, attachment_filename, attachment_content = temporary_note_with_attachment
|
|
note_id = note_data["id"]
|
|
|
|
logger.info(f"Attempting to retrieve attachment '{attachment_filename}' added by fixture for note ID: {note_id}")
|
|
retrieved_content, retrieved_mime = nc_client.get_note_attachment(
|
|
note_id=note_id,
|
|
filename=attachment_filename
|
|
)
|
|
logger.info(f"Attachment retrieved. Mime type: {retrieved_mime}, Size: {len(retrieved_content)} bytes")
|
|
|
|
assert retrieved_content == attachment_content
|
|
assert "text/plain" in retrieved_mime # Fixture uses text/plain
|
|
logger.info("Retrieved attachment content and mime type verified successfully.")
|
|
|
|
def test_attachments_add_to_note_with_category(nc_client: NextcloudClient, temporary_note: dict):
|
|
"""
|
|
Tests adding and retrieving an attachment specifically for a note that has a category.
|
|
Uses temporary_note fixture and adds attachment manually within the test.
|
|
"""
|
|
note_data = temporary_note # Note created by fixture (has category 'TemporaryTesting')
|
|
note_id = note_data["id"]
|
|
note_category = note_data["category"]
|
|
logger.info(f"Using note ID: {note_id} with category '{note_category}' for attachment test.")
|
|
|
|
# Add attachment within the test
|
|
unique_suffix = uuid.uuid4().hex[:8]
|
|
attachment_filename = f"category_attach_{unique_suffix}.txt"
|
|
attachment_content = f"Content for {attachment_filename}".encode('utf-8')
|
|
attachment_mime = "text/plain"
|
|
|
|
logger.info(f"Attempting to add attachment '{attachment_filename}' to note ID: {note_id}")
|
|
upload_response = nc_client.add_note_attachment(
|
|
note_id=note_id,
|
|
filename=attachment_filename,
|
|
content=attachment_content,
|
|
mime_type=attachment_mime
|
|
)
|
|
assert upload_response and "status_code" in upload_response
|
|
assert upload_response["status_code"] in [201, 204]
|
|
logger.info(f"Attachment '{attachment_filename}' added successfully (Status: {upload_response['status_code']}).")
|
|
time.sleep(1)
|
|
|
|
# Get and Verify Attachment
|
|
logger.info(f"Attempting to retrieve attachment '{attachment_filename}' from note ID: {note_id}")
|
|
retrieved_content, retrieved_mime = nc_client.get_note_attachment(
|
|
note_id=note_id,
|
|
filename=attachment_filename
|
|
)
|
|
logger.info(f"Attachment retrieved. Mime type: {retrieved_mime}, Size: {len(retrieved_content)} bytes")
|
|
|
|
assert retrieved_content == attachment_content
|
|
assert attachment_mime in retrieved_mime
|
|
logger.info("Retrieved attachment content and mime type verified successfully for note with category.")
|
|
# Cleanup is handled by the temporary_note fixture
|
|
|
|
def test_attachments_cleanup_on_note_delete(nc_client: NextcloudClient, temporary_note_with_attachment: tuple):
|
|
"""
|
|
Tests that the attachment (and its directory) are deleted when the parent note is deleted.
|
|
Relies on the cleanup mechanism within notes_delete_note and the temporary_note fixture.
|
|
"""
|
|
note_data, attachment_filename, _ = temporary_note_with_attachment
|
|
note_id = note_data["id"]
|
|
|
|
# Fixture setup already added the attachment.
|
|
# Fixture teardown (from temporary_note) will delete the note.
|
|
# We just need to verify the attachment is gone *after* the test finishes
|
|
# and the fixture cleanup runs. However, pytest fixtures don't easily allow
|
|
# checking state *after* cleanup.
|
|
# Instead, we will manually delete the note here and verify the attachment is gone.
|
|
|
|
logger.info(f"Attachment '{attachment_filename}' exists for note {note_id} (added by fixture).")
|
|
|
|
# Manually delete the note
|
|
logger.info(f"Manually deleting note ID: {note_id} within the test.")
|
|
nc_client.notes_delete_note(note_id=note_id)
|
|
logger.info(f"Note ID: {note_id} deleted successfully.")
|
|
time.sleep(1)
|
|
|
|
# Verify Note Is Deleted
|
|
with pytest.raises(HTTPStatusError) as excinfo_note:
|
|
nc_client.notes_get_note(note_id=note_id)
|
|
assert excinfo_note.value.response.status_code == 404
|
|
logger.info(f"Verified note {note_id} deletion (404 received).")
|
|
|
|
# Verify Attachment Is Deleted (via 404 on GET)
|
|
logger.info(f"Verifying attachment '{attachment_filename}' is deleted for note ID: {note_id}")
|
|
with pytest.raises(HTTPStatusError) as excinfo_attach:
|
|
nc_client.get_note_attachment(
|
|
note_id=note_id,
|
|
filename=attachment_filename
|
|
)
|
|
# Expect 404 because the parent directory (.attachments.NOTE_ID) should be gone
|
|
assert excinfo_attach.value.response.status_code == 404
|
|
logger.info(f"Attachment '{attachment_filename}' correctly not found (404) after note deletion.")
|
|
|
|
# Note: The temporary_note fixture will still run its cleanup,
|
|
# but it will find the note already deleted (404) and handle it gracefully.
|