289 lines
10 KiB
Python
289 lines
10 KiB
Python
import tempfile
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
from PySide6.QtCore import QUrl
|
|
from PySide6.QtGui import QDesktopServices
|
|
from PySide6.QtWidgets import QMessageBox, QWidget
|
|
|
|
|
|
def test_open_document_from_db_success(qtbot, app, fresh_db):
|
|
"""Test successfully opening a document."""
|
|
# Import here to avoid circular import issues
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
# Add a project and document
|
|
proj_id = fresh_db.add_project("Test Project")
|
|
doc_path = Path(tempfile.mktemp(suffix=".txt"))
|
|
doc_path.write_text("test content for document")
|
|
|
|
try:
|
|
doc_id = fresh_db.add_document_from_path(proj_id, str(doc_path))
|
|
|
|
# Mock QDesktopServices.openUrl
|
|
with patch.object(QDesktopServices, "openUrl", return_value=True) as mock_open:
|
|
# Call the function
|
|
success = open_document_from_db(
|
|
fresh_db, doc_id, doc_path.name, parent_widget=None
|
|
)
|
|
|
|
# Verify success
|
|
assert success is True
|
|
|
|
# Verify openUrl was called with a QUrl
|
|
assert mock_open.called
|
|
args = mock_open.call_args[0]
|
|
assert isinstance(args[0], QUrl)
|
|
|
|
# Verify the URL points to a local file
|
|
url_string = args[0].toString()
|
|
assert url_string.startswith("file://")
|
|
assert "bouquin_doc_" in url_string
|
|
assert doc_path.suffix in url_string
|
|
finally:
|
|
doc_path.unlink(missing_ok=True)
|
|
|
|
|
|
def test_open_document_from_db_with_parent_widget(qtbot, app, fresh_db):
|
|
"""Test opening a document with a parent widget provided."""
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
# Create a parent widget
|
|
parent = QWidget()
|
|
qtbot.addWidget(parent)
|
|
|
|
# Add a project and document
|
|
proj_id = fresh_db.add_project("Test Project")
|
|
doc_path = Path(tempfile.mktemp(suffix=".pdf"))
|
|
doc_path.write_text("PDF content")
|
|
|
|
try:
|
|
doc_id = fresh_db.add_document_from_path(proj_id, str(doc_path))
|
|
|
|
with patch.object(QDesktopServices, "openUrl", return_value=True) as mock_open:
|
|
success = open_document_from_db(
|
|
fresh_db, doc_id, doc_path.name, parent_widget=parent
|
|
)
|
|
|
|
assert success is True
|
|
assert mock_open.called
|
|
finally:
|
|
doc_path.unlink(missing_ok=True)
|
|
|
|
|
|
def test_open_document_from_db_nonexistent_document(qtbot, app, fresh_db):
|
|
"""Test opening a non-existent document returns False."""
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
# Try to open a document that doesn't exist
|
|
success = open_document_from_db(
|
|
fresh_db, doc_id=99999, file_name="nonexistent.txt", parent_widget=None
|
|
)
|
|
|
|
# Should return False
|
|
assert success is False
|
|
|
|
|
|
def test_open_document_from_db_shows_error_with_parent(qtbot, app, fresh_db):
|
|
"""Test that error dialog is shown when parent widget is provided."""
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
parent = QWidget()
|
|
qtbot.addWidget(parent)
|
|
|
|
# Mock QMessageBox.warning
|
|
with patch.object(QMessageBox, "warning") as mock_warning:
|
|
success = open_document_from_db(
|
|
fresh_db, doc_id=99999, file_name="nonexistent.txt", parent_widget=parent
|
|
)
|
|
|
|
# Should return False and show warning
|
|
assert success is False
|
|
assert mock_warning.called
|
|
|
|
# Verify warning was shown with correct parent
|
|
call_args = mock_warning.call_args[0]
|
|
assert call_args[0] is parent
|
|
|
|
|
|
def test_open_document_from_db_no_error_dialog_without_parent(qtbot, app, fresh_db):
|
|
"""Test that no error dialog is shown when parent widget is None."""
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
with patch.object(QMessageBox, "warning") as mock_warning:
|
|
success = open_document_from_db(
|
|
fresh_db, doc_id=99999, file_name="nonexistent.txt", parent_widget=None
|
|
)
|
|
|
|
# Should return False but NOT show warning
|
|
assert success is False
|
|
assert not mock_warning.called
|
|
|
|
|
|
def test_open_document_from_db_preserves_file_extension(qtbot, app, fresh_db):
|
|
"""Test that the temporary file has the correct extension."""
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
# Test various file extensions
|
|
extensions = [".txt", ".pdf", ".docx", ".xlsx", ".jpg", ".png"]
|
|
|
|
for ext in extensions:
|
|
proj_id = fresh_db.add_project(f"Project for {ext}")
|
|
doc_path = Path(tempfile.mktemp(suffix=ext))
|
|
doc_path.write_text(f"content for {ext}")
|
|
|
|
try:
|
|
doc_id = fresh_db.add_document_from_path(proj_id, str(doc_path))
|
|
|
|
with patch.object(
|
|
QDesktopServices, "openUrl", return_value=True
|
|
) as mock_open:
|
|
open_document_from_db(fresh_db, doc_id, doc_path.name)
|
|
|
|
# Get the URL that was opened
|
|
url = mock_open.call_args[0][0]
|
|
url_string = url.toString()
|
|
|
|
# Verify the extension is preserved
|
|
assert ext in url_string, f"Extension {ext} not found in {url_string}"
|
|
finally:
|
|
doc_path.unlink(missing_ok=True)
|
|
|
|
|
|
def test_open_document_from_db_file_without_extension(qtbot, app, fresh_db):
|
|
"""Test opening a document without a file extension."""
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
proj_id = fresh_db.add_project("Test Project")
|
|
doc_path = Path(tempfile.mktemp()) # No suffix
|
|
doc_path.write_text("content without extension")
|
|
|
|
try:
|
|
doc_id = fresh_db.add_document_from_path(proj_id, str(doc_path))
|
|
|
|
with patch.object(QDesktopServices, "openUrl", return_value=True) as mock_open:
|
|
success = open_document_from_db(fresh_db, doc_id, doc_path.name)
|
|
|
|
# Should still succeed
|
|
assert success is True
|
|
assert mock_open.called
|
|
finally:
|
|
doc_path.unlink(missing_ok=True)
|
|
|
|
|
|
def test_open_document_from_db_desktop_services_failure(qtbot, app, fresh_db):
|
|
"""Test handling when QDesktopServices.openUrl returns False."""
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
proj_id = fresh_db.add_project("Test Project")
|
|
doc_path = Path(tempfile.mktemp(suffix=".txt"))
|
|
doc_path.write_text("test content")
|
|
|
|
try:
|
|
doc_id = fresh_db.add_document_from_path(proj_id, str(doc_path))
|
|
|
|
# Mock openUrl to return False (failure)
|
|
with patch.object(QDesktopServices, "openUrl", return_value=False):
|
|
success = open_document_from_db(fresh_db, doc_id, doc_path.name)
|
|
|
|
# Should return False
|
|
assert success is False
|
|
finally:
|
|
doc_path.unlink(missing_ok=True)
|
|
|
|
|
|
def test_open_document_from_db_binary_content(qtbot, app, fresh_db):
|
|
"""Test opening a document with binary content."""
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
proj_id = fresh_db.add_project("Test Project")
|
|
doc_path = Path(tempfile.mktemp(suffix=".bin"))
|
|
|
|
# Write some binary data
|
|
binary_data = bytes([0, 1, 2, 3, 255, 254, 253])
|
|
doc_path.write_bytes(binary_data)
|
|
|
|
try:
|
|
doc_id = fresh_db.add_document_from_path(proj_id, str(doc_path))
|
|
|
|
with patch.object(QDesktopServices, "openUrl", return_value=True) as mock_open:
|
|
success = open_document_from_db(fresh_db, doc_id, doc_path.name)
|
|
|
|
assert success is True
|
|
assert mock_open.called
|
|
finally:
|
|
doc_path.unlink(missing_ok=True)
|
|
|
|
|
|
def test_open_document_from_db_large_file(qtbot, app, fresh_db):
|
|
"""Test opening a large document."""
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
proj_id = fresh_db.add_project("Test Project")
|
|
doc_path = Path(tempfile.mktemp(suffix=".bin"))
|
|
|
|
# Create a 1MB file
|
|
large_data = b"x" * (1024 * 1024)
|
|
doc_path.write_bytes(large_data)
|
|
|
|
try:
|
|
doc_id = fresh_db.add_document_from_path(proj_id, str(doc_path))
|
|
|
|
with patch.object(QDesktopServices, "openUrl", return_value=True) as mock_open:
|
|
success = open_document_from_db(fresh_db, doc_id, doc_path.name)
|
|
|
|
assert success is True
|
|
assert mock_open.called
|
|
finally:
|
|
doc_path.unlink(missing_ok=True)
|
|
|
|
|
|
def test_open_document_from_db_temp_file_prefix(qtbot, app, fresh_db):
|
|
"""Test that temporary files have the correct prefix."""
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
proj_id = fresh_db.add_project("Test Project")
|
|
doc_path = Path(tempfile.mktemp(suffix=".txt"))
|
|
doc_path.write_text("test")
|
|
|
|
try:
|
|
doc_id = fresh_db.add_document_from_path(proj_id, str(doc_path))
|
|
|
|
with patch.object(QDesktopServices, "openUrl", return_value=True) as mock_open:
|
|
open_document_from_db(fresh_db, doc_id, doc_path.name)
|
|
|
|
url = mock_open.call_args[0][0]
|
|
url_path = url.toLocalFile()
|
|
|
|
# Verify the temp file has the bouquin_doc_ prefix
|
|
assert "bouquin_doc_" in url_path
|
|
finally:
|
|
doc_path.unlink(missing_ok=True)
|
|
|
|
|
|
def test_open_document_from_db_multiple_calls(qtbot, app, fresh_db):
|
|
"""Test opening the same document multiple times."""
|
|
from bouquin.document_utils import open_document_from_db
|
|
|
|
proj_id = fresh_db.add_project("Test Project")
|
|
doc_path = Path(tempfile.mktemp(suffix=".txt"))
|
|
doc_path.write_text("test content")
|
|
|
|
try:
|
|
doc_id = fresh_db.add_document_from_path(proj_id, str(doc_path))
|
|
|
|
with patch.object(QDesktopServices, "openUrl", return_value=True) as mock_open:
|
|
# Open the same document 3 times
|
|
for _ in range(3):
|
|
success = open_document_from_db(fresh_db, doc_id, doc_path.name)
|
|
assert success is True
|
|
|
|
# Should have been called 3 times
|
|
assert mock_open.call_count == 3
|
|
|
|
# Each call should create a different temp file
|
|
call_urls = [call[0][0].toString() for call in mock_open.call_args_list]
|
|
# All URLs should be different (different temp files)
|
|
assert len(set(call_urls)) == 3
|
|
finally:
|
|
doc_path.unlink(missing_ok=True)
|