From 6062e111289f50c2017f6cceee19714b3b90442d Mon Sep 17 00:00:00 2001 From: Frankbz Date: Sat, 9 Nov 2024 17:39:02 -0500 Subject: [PATCH] add gmail test --- pyproject.toml | 1 + test/__init__.py | 1 + test/test_gmail.py | 134 ++++++++++++++++++++++++++++++ {tests => test}/test_gmail_api.py | 6 +- tests/__init__.py | 1 - tests/test_gmail.py | 40 --------- uv.lock | 14 ++++ 7 files changed, 155 insertions(+), 42 deletions(-) create mode 100644 test/__init__.py create mode 100644 test/test_gmail.py rename {tests => test}/test_gmail_api.py (80%) delete mode 100644 tests/__init__.py delete mode 100644 tests/test_gmail.py diff --git a/pyproject.toml b/pyproject.toml index ff3fb42..2a18e85 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,6 +22,7 @@ dependencies = [ "asyncio>=3.4.3", "humanreadable>=0.4.0", "pytest>=8.3.3", + "pytest-mock>=3.14.0", ] [tool.uv] diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/__init__.py @@ -0,0 +1 @@ + diff --git a/test/test_gmail.py b/test/test_gmail.py new file mode 100644 index 0000000..7b2d9e2 --- /dev/null +++ b/test/test_gmail.py @@ -0,0 +1,134 @@ +# pytest test/test_gmail.py -v +import pytest +from datetime import datetime +from unittest.mock import Mock, patch +from src.gmail.client import Gmail + + +@pytest.fixture +def mock_gmail_service(): + """Fixture to mock the Gmail API service""" + with patch("src.gmail.client.build") as mock_build: + mock_service = Mock() + mock_build.return_value = mock_service + yield mock_service + + +@pytest.fixture +def gmail_client(mock_gmail_service): + """Fixture to create a Gmail client with mocked authentication""" + with patch("src.gmail.client.Credentials") as mock_creds: + mock_creds.from_authorized_user_file.return_value = Mock(valid=True) + return Gmail() + + +def test_query_method(gmail_client, mock_gmail_service): + # Mock response data + mock_messages = { + "messages": [ + {"id": "123", "threadId": "thread123"}, + {"id": "456", "threadId": "thread456"}, + ] + } + + # Setup the mock chain + mock_service = mock_gmail_service + mock_service.users.return_value.messages.return_value.list.return_value.execute.return_value = mock_messages + + # Test the query method + start_date = datetime(2024, 10, 30) + end_date = datetime(2024, 10, 31) + messages = list( + gmail_client.query(start_date=start_date, end_date=end_date, max_results=5) + ) + + # Assertions + assert len(messages) == 2 + assert messages[0]["id"] == "123" + assert messages[1]["id"] == "456" + + # Verify the correct query parameters were used + mock_service.users.return_value.messages.return_value.list.assert_called_with( + userId="me", maxResults=5, q="after:2024/10/30 AND before:2024/10/31" + ) + + +def test_get_message(gmail_client, mock_gmail_service): + # Mock response data + mock_message = { + "id": "123", + "payload": { + "headers": [ + {"name": "Subject", "value": "Test Subject"}, + {"name": "From", "value": "sender@example.com"}, + ] + }, + } + + # Setup the mock + mock_service = mock_gmail_service + mock_service.users.return_value.messages.return_value.get.return_value.execute.return_value = mock_message + + # Test get_message + result = gmail_client.get_message("123") + + # Assertions + assert result == mock_message + assert result["payload"]["headers"][0]["value"] == "Test Subject" + + # Verify the correct parameters were used + mock_service.users.return_value.messages.return_value.get.assert_called_with( + userId="me", id="123" + ) + + +def test_search_method(gmail_client, mock_gmail_service): + # Mock response data + mock_search_results = { + "messages": [ + {"id": "789", "threadId": "thread789"}, + {"id": "012", "threadId": "thread012"}, + ] + } + + # Setup the mock + mock_service = mock_gmail_service + mock_service.users.return_value.messages.return_value.list.return_value.execute.return_value = mock_search_results + + # Test search method + search_query = "test query" + results = list(gmail_client.search(search_query, max_results=2)) + + # Assertions + assert len(results) == 2 + assert results[0]["id"] == "789" + assert results[1]["id"] == "012" + + # Verify the correct parameters were used + mock_service.users.return_value.messages.return_value.list.assert_called_with( + userId="me", maxResults=2, q=search_query + ) + + +def test_get_labels(gmail_client, mock_gmail_service): + # Mock response data + mock_labels = { + "labels": [{"id": "INBOX", "name": "INBOX"}, {"id": "SENT", "name": "SENT"}] + } + + # Setup the mock + mock_service = mock_gmail_service + mock_service.users.return_value.labels.return_value.list.return_value.execute.return_value = mock_labels + + # Test get_labels + results = gmail_client.get_labels() + + # Assertions + assert len(results) == 2 + assert results[0]["name"] == "INBOX" + assert results[1]["name"] == "SENT" + + # Verify the correct parameters were used + mock_service.users.return_value.labels.return_value.list.assert_called_with( + userId="me" + ) diff --git a/tests/test_gmail_api.py b/test/test_gmail_api.py similarity index 80% rename from tests/test_gmail_api.py rename to test/test_gmail_api.py index 8e37f2e..963be2a 100644 --- a/tests/test_gmail_api.py +++ b/test/test_gmail_api.py @@ -1,3 +1,7 @@ +# In order to test Google Auth, actual message in your Gmail and API. You can +# replace specific info (like start/end date or message_id) in this file. +# Then compare the output with the actual output in your Gmail. + from datetime import datetime from src.gmail.API import query, get_message, get_labels, search @@ -11,7 +15,7 @@ ## Get Single Message Example # Fetch details of a specific message -message_id = "192e80bb14e565c5" # Replace with actual message ID +message_id = "192e80bb14e565c5" message = get_message(message_id) print(f"Subject: {message.get('subject')}") print(f"Snippet: {message.get('snippet')}") diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index 5c21d1e..0000000 --- a/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# init file diff --git a/tests/test_gmail.py b/tests/test_gmail.py deleted file mode 100644 index 353de60..0000000 --- a/tests/test_gmail.py +++ /dev/null @@ -1,40 +0,0 @@ -from src.gmail.client import Gmail -from datetime import datetime - -gmail = Gmail() - -# testing query() - -for message in gmail.query( - start_date=datetime(2024, 10, 30), end_date=datetime(2024, 10, 31), max_results=5 -): - # Get full message details - full_message = gmail.get_message(message["id"]) - - # Extract subject from headers - headers = full_message["payload"]["headers"] - subject = next( - (header["value"] for header in headers if header["name"] == "Subject"), - "No Subject", - ) - print(f" - Subject: {subject}") - print(f" ID: {message['id']}\n") - - -# test get_message() - -print(gmail.get_message("192df9c0387a516a")) - -# test search() - -search_query = "aaa" -print(f" Searching for: {search_query}") -for message in gmail.search(search_query, max_results=3): - full_message = gmail.get_message(message["id"]) - headers = full_message["payload"]["headers"] - subject = next( - (header["value"] for header in headers if header["name"] == "Subject"), - "No Subject", - ) - print(f" - Subject: {subject}") - print(f" ID: {message['id']}\n") diff --git a/uv.lock b/uv.lock index 72eec49..1670d2d 100644 --- a/uv.lock +++ b/uv.lock @@ -560,6 +560,7 @@ dependencies = [ { name = "openai" }, { name = "pydantic" }, { name = "pytest" }, + { name = "pytest-mock" }, { name = "slack-bolt" }, { name = "slack-sdk" }, { name = "sqlalchemy" }, @@ -588,6 +589,7 @@ requires-dist = [ { name = "openai", specifier = ">=1.50.2" }, { name = "pydantic", specifier = ">=2.9.2" }, { name = "pytest", specifier = ">=8.3.3" }, + { name = "pytest-mock", specifier = ">=3.14.0" }, { name = "slack-bolt", specifier = ">=1.20.1" }, { name = "slack-sdk", specifier = ">=3.33.1" }, { name = "sqlalchemy", specifier = ">=2.0.35" }, @@ -885,6 +887,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 }, ] +[[package]] +name = "pytest-mock" +version = "3.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863 }, +] + [[package]] name = "requests" version = "2.32.3"