50910da3e0
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
123 lines
4.3 KiB
Python
123 lines
4.3 KiB
Python
"""Extended tests for app/tasks/imap_tasks.py module."""
|
|
import os
|
|
import json
|
|
import pytest
|
|
from datetime import datetime, timezone
|
|
from unittest.mock import patch, MagicMock
|
|
from email.message import EmailMessage
|
|
|
|
from app.tasks.imap_tasks import (
|
|
save_processed_emails,
|
|
load_processed_emails,
|
|
fetch_attachments_and_enqueue,
|
|
find_all_mail_xlist,
|
|
)
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestSaveProcessedEmails:
|
|
"""Tests for save_processed_emails function."""
|
|
|
|
@patch("app.tasks.imap_tasks.CACHE_FILE", "/tmp/test_save_processed.json")
|
|
def test_saves_to_file(self):
|
|
"""Test that processed emails are saved to file."""
|
|
emails = {"msg-1": "2024-01-01T00:00:00", "msg-2": "2024-01-02T00:00:00"}
|
|
save_processed_emails(emails)
|
|
assert os.path.exists("/tmp/test_save_processed.json")
|
|
with open("/tmp/test_save_processed.json") as f:
|
|
loaded = json.load(f)
|
|
assert loaded == emails
|
|
os.remove("/tmp/test_save_processed.json")
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestFetchAttachmentsExtended:
|
|
"""Extended tests for fetch_attachments_and_enqueue."""
|
|
|
|
@patch("app.tasks.imap_tasks.process_document")
|
|
@patch("app.tasks.imap_tasks.convert_to_pdf")
|
|
def test_processes_pdf_by_extension(self, mock_convert, mock_process, tmp_path):
|
|
"""Test PDF detection by extension even with wrong MIME type."""
|
|
msg = EmailMessage()
|
|
msg["Subject"] = "Test"
|
|
# Create attachment with wrong MIME type but .pdf extension
|
|
msg.add_attachment(
|
|
b"%PDF-1.4", maintype="application", subtype="octet-stream", filename="invoice.pdf"
|
|
)
|
|
|
|
with patch("app.tasks.imap_tasks.settings") as mock_settings:
|
|
mock_settings.workdir = str(tmp_path)
|
|
result = fetch_attachments_and_enqueue(msg)
|
|
|
|
assert result is True
|
|
mock_process.delay.assert_called_once()
|
|
|
|
@patch("app.tasks.imap_tasks.process_document")
|
|
@patch("app.tasks.imap_tasks.convert_to_pdf")
|
|
def test_processes_text_attachment(self, mock_convert, mock_process, tmp_path):
|
|
"""Test text/plain attachment is sent for conversion."""
|
|
msg = EmailMessage()
|
|
msg["Subject"] = "Test"
|
|
msg.add_attachment(b"Hello world", maintype="text", subtype="plain", filename="notes.txt")
|
|
|
|
with patch("app.tasks.imap_tasks.settings") as mock_settings:
|
|
mock_settings.workdir = str(tmp_path)
|
|
result = fetch_attachments_and_enqueue(msg)
|
|
|
|
assert result is True
|
|
mock_convert.delay.assert_called_once()
|
|
|
|
@patch("app.tasks.imap_tasks.process_document")
|
|
@patch("app.tasks.imap_tasks.convert_to_pdf")
|
|
def test_skips_multipart(self, mock_convert, mock_process):
|
|
"""Test that multipart parts are skipped."""
|
|
msg = EmailMessage()
|
|
msg["Subject"] = "Test"
|
|
msg.set_content("Hello body") # multipart text is skipped
|
|
|
|
result = fetch_attachments_and_enqueue(msg)
|
|
assert result is False
|
|
|
|
@patch("app.tasks.imap_tasks.process_document")
|
|
@patch("app.tasks.imap_tasks.convert_to_pdf")
|
|
def test_no_attachments(self, mock_convert, mock_process):
|
|
"""Test email with no attachments."""
|
|
msg = EmailMessage()
|
|
msg["Subject"] = "No attachments"
|
|
msg.set_content("Plain text body")
|
|
|
|
result = fetch_attachments_and_enqueue(msg)
|
|
assert result is False
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestFindAllMailXlist:
|
|
"""Tests for find_all_mail_xlist function."""
|
|
|
|
def test_finds_all_mail_via_xlist(self):
|
|
"""Test finding All Mail folder via XLIST."""
|
|
mock_mail = MagicMock()
|
|
mock_mail._new_tag.return_value = b"A001"
|
|
|
|
# Simulate XLIST response
|
|
mock_mail.readline.side_effect = [
|
|
b'* XLIST (\\AllMail) "/" "[Gmail]/All Mail"\r\n',
|
|
b"A001 OK XLIST completed\r\n",
|
|
]
|
|
|
|
result = find_all_mail_xlist(mock_mail)
|
|
assert result == "[Gmail]/All Mail"
|
|
|
|
def test_returns_none_when_no_allmail(self):
|
|
"""Test returns None when XLIST doesn't find All Mail."""
|
|
mock_mail = MagicMock()
|
|
mock_mail._new_tag.return_value = b"A001"
|
|
|
|
mock_mail.readline.side_effect = [
|
|
b'* XLIST (\\Inbox) "/" "INBOX"\r\n',
|
|
b"A001 OK XLIST completed\r\n",
|
|
]
|
|
|
|
result = find_all_mail_xlist(mock_mail)
|
|
assert result is None
|