add email_login unit test

This commit is contained in:
Zhou Tuo 2024-02-07 07:59:54 +00:00
parent f31f371d53
commit 4a991b4cd4
3 changed files with 79 additions and 27 deletions

View file

@ -9,14 +9,15 @@ from metagpt.roles.ci.code_interpreter import CodeInterpreter
async def main():
# prompt_response = """I will give you your Outlook email account(englishgpt@outlook.com) and password(the outlook_email_password item in the environment variable). You need to find the latest email in my inbox with the sender's suffix @qq.com and reply to him "Thank you! I have received your email~"""""
prompt_summary = """I will give you your Outlook email account(englishgpt@outlook.com) and password(outlook_email_password item in the environment variable).
# For email response prompt
# prompt = """I will give you your Outlook email account(englishgpt@outlook.com) and password(the outlook_email_password item in the environment variable). You need to find the latest email in my inbox with the sender's suffix @qq.com and reply to him "Thank you! I have received your email~"""""
prompt = """I will give you your Outlook email account(englishgpt@outlook.com) and password(outlook_email_password item in the environment variable).
Firstly, Please help me present the latest 5 senders and full letter contents.
Then, summarize each of the 5 emails into one sentence with Chinese(you can do this by yourself, don't need import other models to do this) and output them in a markdown format."""
# ci_response = CodeInterpreter(goal=prompt_response, use_tools=True)
ci_summary = CodeInterpreter(goal=prompt_summary, use_tools=True)
await ci_summary.run(prompt_summary)
ci = CodeInterpreter(use_tools=True)
await ci.run(prompt)
if __name__ == "__main__":

View file

@ -1,8 +1,29 @@
from imap_tools import MailBox
from metagpt.logs import logger
from metagpt.tools.tool_registry import register_tool
from metagpt.tools.tool_type import ToolType
# Define a dictionary mapping email domains to their IMAP server addresses
IMAP_SERVERS = {
"outlook.com": "imap-mail.outlook.com", # Outlook
"163.com": "imap.163.com", # 163 Mail
"qq.com": "imap.qq.com", # QQ Mail
"gmail.com": "imap.gmail.com", # Gmail
"yahoo.com": "imap.mail.yahoo.com", # Yahoo Mail
"icloud.com": "imap.mail.me.com", # iCloud Mail
"hotmail.com": "imap-mail.outlook.com", # Hotmail (同 Outlook)
"live.com": "imap-mail.outlook.com", # Live (同 Outlook)
"sina.com": "imap.sina.com", # Sina Mail
"sohu.com": "imap.sohu.com", # Sohu Mail
"yahoo.co.jp": "imap.mail.yahoo.co.jp", # Yahoo Mail Japan
"yandex.com": "imap.yandex.com", # Yandex Mail
"mail.ru": "imap.mail.ru", # Mail.ru
"aol.com": "imap.aol.com", # AOL Mail
"gmx.com": "imap.gmx.com", # GMX Mail
"zoho.com": "imap.zoho.com", # Zoho Mail
}
@register_tool(tool_type=ToolType.EMAIL_LOGIN.type_name)
def email_login_imap(email_address, email_password):
@ -17,34 +38,14 @@ def email_login_imap(email_address, email_password):
object: The imap_tools's MailBox object returned after successfully connecting to the mailbox through imap_tools, including various information about this account (email, etc.), or None if login fails.
"""
# Define a dictionary mapping email domains to their IMAP server addresses
imap_servers = {
"outlook.com": "imap-mail.outlook.com", # Outlook
"163.com": "imap.163.com", # 163 Mail
"qq.com": "imap.qq.com", # QQ Mail
"gmail.com": "imap.gmail.com", # Gmail
"yahoo.com": "imap.mail.yahoo.com", # Yahoo Mail
"icloud.com": "imap.mail.me.com", # iCloud Mail
"hotmail.com": "imap-mail.outlook.com", # Hotmail (同 Outlook)
"live.com": "imap-mail.outlook.com", # Live (同 Outlook)
"sina.com": "imap.sina.com", # Sina Mail
"sohu.com": "imap.sohu.com", # Sohu Mail
"yahoo.co.jp": "imap.mail.yahoo.co.jp", # Yahoo Mail Japan
"yandex.com": "imap.yandex.com", # Yandex Mail
"mail.ru": "imap.mail.ru", # Mail.ru
"aol.com": "imap.aol.com", # AOL Mail
"gmx.com": "imap.gmx.com", # GMX Mail
"zoho.com": "imap.zoho.com", # Zoho Mail
}
# Extract the domain from the email address
domain = email_address.split("@")[-1]
# Determine the correct IMAP server
imap_server = imap_servers.get(domain)
imap_server = IMAP_SERVERS.get(domain)
if not imap_server:
print(f"IMAP server for {domain} not found.")
logger.error(f"IMAP server for {domain} not found.")
return None
# Attempt to log in to the email account

View file

@ -0,0 +1,50 @@
import os
from unittest.mock import Mock, patch
import pytest
from metagpt.tools.libs.email_login import email_login_imap
# Configuration for the test IMAP servers
TEST_IMAP_SERVERS = {"outlook.com": "imap-mail.outlook.com"}
# Setup correct and incorrect email information
correct_email_address = "englishgpt@outlook.com"
correct_email_password = os.environ.get("outlook_email_password")
incorrect_email_address = "test@unknown.com"
incorrect_email_password = "incorrect_password"
@pytest.fixture
def imap_server_setup():
# Use patch to mock the behavior of MailBox from the correct module path
with patch("metagpt.tools.libs.email_login.MailBox") as mock_mailbox:
# Setup for successful login
mock_mail_instance = Mock()
mock_mail_instance.login.return_value = mock_mail_instance
mock_mailbox.return_value = mock_mail_instance
yield mock_mail_instance
def test_email_login_imap_success(imap_server_setup):
# Mock successful login
mailbox = email_login_imap(correct_email_address, correct_email_password)
assert mailbox is not None
# Correctly assert that the login method of the MailBox mock was called with the correct arguments
imap_server_setup.login.assert_called_with(correct_email_address, correct_email_password)
def test_email_login_imap_failure_due_to_incorrect_server(imap_server_setup):
# Attempt to login with an incorrect server
mailbox = email_login_imap(incorrect_email_address, incorrect_email_password)
assert mailbox is None
def test_email_login_imap_failure_due_to_wrong_credentials(imap_server_setup):
# Configure mock to throw an exception to simulate login failure due to incorrect credentials
imap_server_setup.login.side_effect = Exception("Login failed")
# Attempt to login which should simulate a failure
mailbox = email_login_imap(correct_email_address, incorrect_email_password)
assert mailbox is None
# Verify that the login method was called with the expected arguments
imap_server_setup.login.assert_called_with(correct_email_address, incorrect_email_password)