feat(cleaner): ✨ add command prune
this new command will be called by cron-like process to clean purge old logs and old mails. All files were formatted and mail_utils was renamed in utils since it now defines utility function not only for mail functions.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Entry point to all package tests."""
|
||||
|
||||
+8
-3
@@ -6,7 +6,7 @@ from unittest.mock import MagicMock
|
||||
import pytest
|
||||
from exchangelib import Account, Message
|
||||
|
||||
from logwatcher.config import FIXTURE_PATH
|
||||
from logwatcher.config import FIXTURE_PATH, OUTPUT_PATH
|
||||
from logwatcher.logging_config import setup_logging
|
||||
|
||||
# original log directory
|
||||
@@ -19,18 +19,21 @@ VALID_LOG_DIR = FIXTURE_PATH / "valid_logs"
|
||||
INVALID_LOG_DIR = FIXTURE_PATH / "invalid_logs"
|
||||
|
||||
# define temp directory only for testing
|
||||
os.environ["PYTEST_DEBUG_TEMPROOT"] = str(Path("output/test").absolute())
|
||||
os.environ["PYTEST_DEBUG_TEMPROOT"] = str(OUTPUT_PATH)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tmp_log_file(tmp_path):
|
||||
"""Return path of logs logwatcher related."""
|
||||
return tmp_path / "logwatcher_test.log"
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def tmp_setup_logging(tmp_log_file):
|
||||
"""Redirige les logs vers un dossier temporaire pendant les tests."""
|
||||
setup_logging(file_path=tmp_log_file)
|
||||
|
||||
|
||||
@pytest.fixture(name="original_log_dir")
|
||||
def original_log_dir_fixture() -> Path:
|
||||
"""Return log directory containing real logs.
|
||||
@@ -41,6 +44,7 @@ def original_log_dir_fixture() -> Path:
|
||||
"""
|
||||
return FIXTURE_PATH / "original_logs"
|
||||
|
||||
|
||||
@pytest.fixture(name="valid_log_dir")
|
||||
def valid_log_dir_fixture() -> Path:
|
||||
"""Return log directory containing only valid logs.
|
||||
@@ -51,6 +55,7 @@ def valid_log_dir_fixture() -> Path:
|
||||
"""
|
||||
return FIXTURE_PATH / "valid_logs"
|
||||
|
||||
|
||||
@pytest.fixture(name="invalid_log_dir")
|
||||
def invalid_log_dir_fixture() -> Path:
|
||||
"""Return log directory containing invalid logs.
|
||||
@@ -78,4 +83,4 @@ def make_mock_account():
|
||||
logs_folder.glob.return_value = [analyzed_folder] if analyzed_folder else []
|
||||
return account
|
||||
|
||||
return _make_mock_account
|
||||
return _make_mock_account
|
||||
|
||||
+28
-44
@@ -8,7 +8,7 @@ from unittest.mock import MagicMock
|
||||
|
||||
|
||||
from logwatcher import __version__
|
||||
from logwatcher.cli import _get_files_from_dir, _is_log_file, app
|
||||
from logwatcher.cli import _get_files_from_dir, app
|
||||
|
||||
runner = CliRunner()
|
||||
|
||||
@@ -62,33 +62,9 @@ def test_version_cli():
|
||||
assert f"logwatcher version: {__version__}" in result.output
|
||||
|
||||
|
||||
def test_is_log_file(tmp_path: Path):
|
||||
"""Assert only .log, .txt or file without extensions are valid.
|
||||
|
||||
Args:
|
||||
tmp_path: Temporary root path for testing results
|
||||
|
||||
"""
|
||||
# set up files
|
||||
Path(tmp_path / "a.log").touch()
|
||||
Path(tmp_path / "a.txt").touch()
|
||||
Path(tmp_path / "a.csv").touch()
|
||||
Path(tmp_path / "a.py").touch()
|
||||
Path(tmp_path / "a").touch()
|
||||
Path(tmp_path / "a.pdf").touch()
|
||||
|
||||
# test
|
||||
assert _is_log_file(Path(tmp_path / "a.log"))
|
||||
assert _is_log_file(Path(tmp_path / "a.txt"))
|
||||
assert _is_log_file(Path(tmp_path / "a")) # without extensions
|
||||
assert not _is_log_file(Path(tmp_path / "a.csv"))
|
||||
assert not _is_log_file(Path(tmp_path / "a.py"))
|
||||
assert not _is_log_file(Path(tmp_path / "a.pdf"))
|
||||
|
||||
|
||||
def test_get_files_from_dir_empty_dir(tmp_path: Path):
|
||||
"""Assert that a non-existing directory (or wrong path) cannot be given as a working input directory.
|
||||
|
||||
|
||||
Assert that everything works even if the directory is empty.
|
||||
|
||||
Args:
|
||||
@@ -154,7 +130,7 @@ def test_cli_from_files_input_files_and_input_dir(output_path: Path):
|
||||
|
||||
def test_cli_from_files_neither_input_files_nor_input_dir():
|
||||
"""Test calling cli without providing input files or input dir options.
|
||||
|
||||
|
||||
Must return an error on provided parameters (BadParameter = exit code 2)
|
||||
|
||||
"""
|
||||
@@ -163,7 +139,9 @@ def test_cli_from_files_neither_input_files_nor_input_dir():
|
||||
assert "Either input_files or input_dir must be provided" in results.output
|
||||
|
||||
|
||||
def test_cli_from_files_bad_input_file(tmp_path: Path, output_path: Path, invalid_log_dir: Path):
|
||||
def test_cli_from_files_bad_input_file(
|
||||
tmp_path: Path, output_path: Path, invalid_log_dir: Path
|
||||
):
|
||||
"""Test calling cli with bad input file (directory instead of file).
|
||||
|
||||
Must return an exit code at 1 and the ValueError exception raised
|
||||
@@ -277,7 +255,7 @@ def test_cli_from_files_input_files_or_input_dir(
|
||||
|
||||
def test_cli_from_files_input_files_one_file(valid_log_dir: Path, output_path: Path):
|
||||
"""Assert that CLI can analyze a single valid file.
|
||||
|
||||
|
||||
Args:
|
||||
valid_log_dir: Fixture of directory of valid logs
|
||||
output_path: Fixture of directory receiving all file generated during process.
|
||||
@@ -405,22 +383,22 @@ def test_cli_from_files_valid_logs(output_path: Path, valid_log_dir: Path):
|
||||
|
||||
def test_cli_from_mails_no_output_dir(monkeypatch, make_mock_account):
|
||||
"""Assert everything works when no output_path is provided.
|
||||
|
||||
|
||||
Must use "output/" directory, located in project root.
|
||||
|
||||
|
||||
|
||||
"""
|
||||
messages = [
|
||||
Message(subject="subject test 1", text_body="body test 1"),
|
||||
Message(subject="subject test 2", text_body="body test 2"),
|
||||
Message(subject="subject test 3", text_body="body test 3")
|
||||
Message(subject="subject test 3", text_body="body test 3"),
|
||||
]
|
||||
|
||||
with monkeypatch.context() as m:
|
||||
m.setattr("logwatcher.cli.connect_to_mailbox", lambda: make_mock_account(messages=messages, analyzed_folder="Analyzed"))
|
||||
m.setattr(
|
||||
"logwatcher.cli.connect_to_mailbox",
|
||||
lambda: make_mock_account(messages=messages, analyzed_folder="Analyzed"),
|
||||
)
|
||||
m.setattr("logwatcher.notifier.Message.send", MagicMock(return_value=None))
|
||||
|
||||
|
||||
arguments = ["from-mails"]
|
||||
results = runner.invoke(app, arguments)
|
||||
assert results.exit_code == 0
|
||||
@@ -428,7 +406,7 @@ def test_cli_from_mails_no_output_dir(monkeypatch, make_mock_account):
|
||||
|
||||
def test_cli_from_mails_invalid_output_dir(tmp_path, monkeypatch):
|
||||
"""Assert that if output_dir is a file, raise an error.
|
||||
|
||||
|
||||
Args:
|
||||
tmp_path: path where to store temporarily output files
|
||||
monkeypatch: used to fake a context and method calls
|
||||
@@ -442,9 +420,12 @@ def test_cli_from_mails_invalid_output_dir(tmp_path, monkeypatch):
|
||||
]
|
||||
|
||||
with monkeypatch.context() as m:
|
||||
m.setattr("logwatcher.cli.connect_to_mailbox", lambda: make_mock_account(messages=messages, analyzed_folder="Analyzed"))
|
||||
m.setattr(
|
||||
"logwatcher.cli.connect_to_mailbox",
|
||||
lambda: make_mock_account(messages=messages, analyzed_folder="Analyzed"),
|
||||
)
|
||||
m.setattr("logwatcher.notifier.Message.send", MagicMock(return_value=None))
|
||||
|
||||
|
||||
arguments = ["from-mails", "--output-dir", bad_output_dir]
|
||||
results = runner.invoke(app, arguments)
|
||||
assert results.exit_code != 0
|
||||
@@ -452,7 +433,7 @@ def test_cli_from_mails_invalid_output_dir(tmp_path, monkeypatch):
|
||||
|
||||
def test_cli_from_mails_valid_output_dir(tmp_path, monkeypatch, make_mock_account):
|
||||
"""Assert everything works when a valid output_path is provided.
|
||||
|
||||
|
||||
Args:
|
||||
tmp_path: path where to store temporarily output files
|
||||
monkeypatch: used to fake a context and method calls
|
||||
@@ -464,16 +445,19 @@ def test_cli_from_mails_valid_output_dir(tmp_path, monkeypatch, make_mock_accoun
|
||||
messages = [
|
||||
Message(subject="subject test 1", text_body="body test 1"),
|
||||
Message(subject="subject test 2", text_body="body test 2"),
|
||||
Message(subject="subject test 3", text_body="body test 3")
|
||||
Message(subject="subject test 3", text_body="body test 3"),
|
||||
]
|
||||
|
||||
with monkeypatch.context() as m:
|
||||
m.setattr("logwatcher.cli.connect_to_mailbox", lambda: make_mock_account(messages=messages, analyzed_folder="Analyzed"))
|
||||
m.setattr(
|
||||
"logwatcher.cli.connect_to_mailbox",
|
||||
lambda: make_mock_account(messages=messages, analyzed_folder="Analyzed"),
|
||||
)
|
||||
m.setattr("logwatcher.notifier.Message.send", MagicMock(return_value=None))
|
||||
|
||||
|
||||
arguments = ["from-mails", "--output-dir", output_path]
|
||||
results = runner.invoke(app, arguments)
|
||||
|
||||
|
||||
assert results.exit_code == 0
|
||||
output_children = list(output_path.iterdir())
|
||||
expected = ["n2.log", "all.log", "other.log"]
|
||||
|
||||
@@ -20,7 +20,7 @@ def test_setup_handler(tmp_log_file):
|
||||
|
||||
def test_count_of_handler(tmp_log_file):
|
||||
"""Assert `setup_handler` instanciate exactly one StreamHandler and one FileHandler.
|
||||
|
||||
|
||||
Must have exactly two handlers in total.
|
||||
"""
|
||||
logger = getLogger()
|
||||
@@ -82,7 +82,7 @@ def test_modified_format():
|
||||
|
||||
def test_logging_in_correct_path(tmp_log_file):
|
||||
"""Assert log file is correctly written in output directory.
|
||||
|
||||
|
||||
Check content of the file. It must contain logs from CRITICAL to DEBUG level.
|
||||
"""
|
||||
logger = logging.getLogger("logwatcher")
|
||||
|
||||
+30
-12
@@ -11,46 +11,64 @@ def test_valid_log_entry():
|
||||
LogEntry(
|
||||
server_ip="192.168.13.27",
|
||||
mdc_server_name="MDC_720",
|
||||
start_time=datetime.strptime("18/07/2026 11:34:41", DATETIME_FORMAT).astimezone(FRENCH_TIMEZONE),
|
||||
start_time=datetime.strptime("18/07/2026 11:34:41", DATETIME_FORMAT).astimezone(
|
||||
FRENCH_TIMEZONE
|
||||
),
|
||||
store_name="PECCOUD",
|
||||
error_time=datetime.strptime("18/07/2026 11:35:58", DATETIME_FORMAT).astimezone(FRENCH_TIMEZONE),
|
||||
error_time=datetime.strptime("18/07/2026 11:35:58", DATETIME_FORMAT).astimezone(
|
||||
FRENCH_TIMEZONE
|
||||
),
|
||||
error_message="Erreur FTP SDUpdatePrixISF : Requested action not taken",
|
||||
raw_line="\\\\192.168.13.27\\e\\MDC_720\\Logs\\26\\07\\18\\20260718113428.txt [18/07/2026 11:34:41] DOSSIER EN COURS : PECCOUD [18/07/2026 11:35:58] Erreur FTP SDUpdatePrixISF : Requested action not taken"
|
||||
raw_line="\\\\192.168.13.27\\e\\MDC_720\\Logs\\26\\07\\18\\20260718113428.txt [18/07/2026 11:34:41] DOSSIER EN COURS : PECCOUD [18/07/2026 11:35:58] Erreur FTP SDUpdatePrixISF : Requested action not taken",
|
||||
)
|
||||
|
||||
|
||||
def test_log_entry_invalid_dates():
|
||||
"""Assert a log entry cannot be created if start time is not later than error time."""
|
||||
with pytest.raises(ValueError, match="Error in date-times"):
|
||||
LogEntry(
|
||||
server_ip="192.168.13.27",
|
||||
mdc_server_name="MDC_720",
|
||||
start_time=datetime.strptime("18/07/2026 11:35:58", DATETIME_FORMAT).astimezone(FRENCH_TIMEZONE),
|
||||
start_time=datetime.strptime(
|
||||
"18/07/2026 11:35:58", DATETIME_FORMAT
|
||||
).astimezone(FRENCH_TIMEZONE),
|
||||
store_name="PECCOUD",
|
||||
error_time=datetime.strptime("18/07/2026 11:34:41", DATETIME_FORMAT).astimezone(FRENCH_TIMEZONE),
|
||||
error_time=datetime.strptime(
|
||||
"18/07/2026 11:34:41", DATETIME_FORMAT
|
||||
).astimezone(FRENCH_TIMEZONE),
|
||||
error_message="Erreur FTP SDUpdatePrixISF : Requested action not taken",
|
||||
raw_line="\\\\192.168.13.27\\e\\MDC_720\\Logs\\26\\07\\18\\20260718113428.txt [18/07/2026 11:34:41] DOSSIER EN COURS : PECCOUD [18/07/2026 11:35:58] Erreur FTP SDUpdatePrixISF : Requested action not taken"
|
||||
raw_line="\\\\192.168.13.27\\e\\MDC_720\\Logs\\26\\07\\18\\20260718113428.txt [18/07/2026 11:34:41] DOSSIER EN COURS : PECCOUD [18/07/2026 11:35:58] Erreur FTP SDUpdatePrixISF : Requested action not taken",
|
||||
)
|
||||
|
||||
|
||||
def test_equals_models():
|
||||
"""Assert two models are equals if they have the same value as attributes."""
|
||||
log_entry_1 = LogEntry(
|
||||
server_ip="192.168.13.27",
|
||||
mdc_server_name="MDC_720",
|
||||
start_time=datetime.strptime("18/07/2026 11:34:41", DATETIME_FORMAT).astimezone(FRENCH_TIMEZONE),
|
||||
start_time=datetime.strptime("18/07/2026 11:34:41", DATETIME_FORMAT).astimezone(
|
||||
FRENCH_TIMEZONE
|
||||
),
|
||||
store_name="PECCOUD",
|
||||
error_time=datetime.strptime("18/07/2026 11:35:58", DATETIME_FORMAT).astimezone(FRENCH_TIMEZONE),
|
||||
error_time=datetime.strptime("18/07/2026 11:35:58", DATETIME_FORMAT).astimezone(
|
||||
FRENCH_TIMEZONE
|
||||
),
|
||||
error_message="Erreur FTP SDUpdatePrixISF : Requested action not taken",
|
||||
raw_line="\\\\192.168.13.27\\e\\MDC_720\\Logs\\26\\07\\18\\20260718113428.txt [18/07/2026 11:34:41] DOSSIER EN COURS : PECCOUD [18/07/2026 11:35:58] Erreur FTP SDUpdatePrixISF : Requested action not taken"
|
||||
raw_line="\\\\192.168.13.27\\e\\MDC_720\\Logs\\26\\07\\18\\20260718113428.txt [18/07/2026 11:34:41] DOSSIER EN COURS : PECCOUD [18/07/2026 11:35:58] Erreur FTP SDUpdatePrixISF : Requested action not taken",
|
||||
)
|
||||
|
||||
log_entry_2 = LogEntry(
|
||||
server_ip="192.168.13.27",
|
||||
mdc_server_name="MDC_720",
|
||||
start_time=datetime.strptime("18/07/2026 11:34:41", DATETIME_FORMAT).astimezone(FRENCH_TIMEZONE),
|
||||
start_time=datetime.strptime("18/07/2026 11:34:41", DATETIME_FORMAT).astimezone(
|
||||
FRENCH_TIMEZONE
|
||||
),
|
||||
store_name="PECCOUD",
|
||||
error_time=datetime.strptime("18/07/2026 11:35:58", DATETIME_FORMAT).astimezone(FRENCH_TIMEZONE),
|
||||
error_time=datetime.strptime("18/07/2026 11:35:58", DATETIME_FORMAT).astimezone(
|
||||
FRENCH_TIMEZONE
|
||||
),
|
||||
error_message="Erreur FTP SDUpdatePrixISF : Requested action not taken",
|
||||
raw_line="\\\\192.168.13.27\\e\\MDC_720\\Logs\\26\\07\\18\\20260718113428.txt [18/07/2026 11:34:41] DOSSIER EN COURS : PECCOUD [18/07/2026 11:35:58] Erreur FTP SDUpdatePrixISF : Requested action not taken"
|
||||
raw_line="\\\\192.168.13.27\\e\\MDC_720\\Logs\\26\\07\\18\\20260718113428.txt [18/07/2026 11:34:41] DOSSIER EN COURS : PECCOUD [18/07/2026 11:35:58] Erreur FTP SDUpdatePrixISF : Requested action not taken",
|
||||
)
|
||||
|
||||
assert log_entry_1 == log_entry_2
|
||||
|
||||
+26
-8
@@ -11,23 +11,37 @@ def mock_get_or_create_folder(account, folder_name): # noqa: D103
|
||||
return folder_name
|
||||
|
||||
|
||||
@pytest.mark.parametrize("vars", [("N2_REPORT_SUBJECT", "N2_REPORT_RECIPIENTS"), ("N2_REPORT_RECIPIENTS", "N2_REPORT_SUBJECT")])
|
||||
def test_send_n2_report_missing_recipients_env(vars, monkeypatch, ):
|
||||
@pytest.mark.parametrize(
|
||||
"vars",
|
||||
[
|
||||
("N2_REPORT_SUBJECT", "N2_REPORT_RECIPIENTS"),
|
||||
("N2_REPORT_RECIPIENTS", "N2_REPORT_SUBJECT"),
|
||||
],
|
||||
)
|
||||
def test_send_n2_report_missing_recipients_env(vars, monkeypatch):
|
||||
"""Assert that missing values in environmnent file raises KeyError."""
|
||||
monkeypatch.delenv("N2_REPORT_RECIPIENTS")
|
||||
monkeypatch.delenv("N2_REPORT_SUBJECT")
|
||||
monkeypatch.setenv(vars[0], "test")
|
||||
|
||||
|
||||
with pytest.raises(KeyError) as err:
|
||||
send_n2_report(account=MagicMock(), summary="summary", n2_log_file=MagicMock())
|
||||
|
||||
assert vars[1] in err.value.args
|
||||
|
||||
|
||||
@pytest.mark.parametrize("recipients", ["mail@client.fr", "mail@ client.fr ", "mail1@client.fr,mail2@client.fr,mail3@client.fr", "mail1@client.fr , mail2@client.fr , mail3@client.fr"])
|
||||
@pytest.mark.parametrize(
|
||||
"recipients",
|
||||
[
|
||||
"mail@client.fr",
|
||||
"mail@ client.fr ",
|
||||
"mail1@client.fr,mail2@client.fr,mail3@client.fr",
|
||||
"mail1@client.fr , mail2@client.fr , mail3@client.fr",
|
||||
],
|
||||
)
|
||||
def test_send_n2_report_multiple_recipients(recipients, make_mock_account, monkeypatch):
|
||||
"""Assert gathering multiple account as recipients from env file is valid.
|
||||
|
||||
|
||||
Tests with value having space characters.
|
||||
Mails must be seperated by a comma.
|
||||
|
||||
@@ -35,12 +49,16 @@ def test_send_n2_report_multiple_recipients(recipients, make_mock_account, monke
|
||||
recipients: e-mail recipients in one string
|
||||
make_mock_account: return a fake account used for tests
|
||||
monkeypatch: used to change environment variables and functions accross the script
|
||||
|
||||
|
||||
"""
|
||||
monkeypatch.setenv("N2_REPORT_SUBJECT", "test")
|
||||
monkeypatch.setenv("N2_REPORT_RECIPIENTS", "mail@client.fr")
|
||||
|
||||
with monkeypatch.context() as m:
|
||||
m.setattr("logwatcher.notifier.get_or_create_folder", mock_get_or_create_folder)
|
||||
m.setattr("logwatcher.notifier.Message.send", MagicMock(id="1", return_value=None))
|
||||
send_n2_report(account=make_mock_account(), summary="summary", n2_log_file=MagicMock())
|
||||
m.setattr(
|
||||
"logwatcher.notifier.Message.send", MagicMock(id="1", return_value=None)
|
||||
)
|
||||
send_n2_report(
|
||||
account=make_mock_account(), summary="summary", n2_log_file=MagicMock()
|
||||
)
|
||||
|
||||
@@ -19,7 +19,7 @@ def empty_log_file_fixture(invalid_log_dir: Path) -> Path:
|
||||
@pytest.fixture(name="bad_log_file")
|
||||
def bad_log_file_fixture(invalid_log_dir: Path) -> Path:
|
||||
"""Path of a file containing only incorrectly formatted lines.
|
||||
|
||||
|
||||
Each line fails at a different point in LOG_PATTERN
|
||||
(invalid IP, missing timestamp, missing DOSSIER EN COURS, etc.).
|
||||
No LogEntry should be produced.
|
||||
@@ -93,7 +93,7 @@ def test_parse_lines():
|
||||
|
||||
|
||||
def test_parse_valid_lines(specific_logs: Path):
|
||||
"""Assert parse_lines works for all valid lines."""
|
||||
"""Assert parse_lines works for all valid lines."""
|
||||
# selected valid logs
|
||||
with open(specific_logs, "r") as file:
|
||||
log_lines = file.readlines()
|
||||
|
||||
@@ -1,6 +1,31 @@
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from logwatcher.mail_utils import get_or_create_folder
|
||||
from logwatcher.utils import get_or_create_folder, is_log_file
|
||||
|
||||
|
||||
def test_is_log_file(tmp_path: Path):
|
||||
"""Assert only .log, .txt or file without extensions are valid.
|
||||
|
||||
Args:
|
||||
tmp_path: Temporary root path for testing results
|
||||
|
||||
"""
|
||||
# set up files
|
||||
Path(tmp_path / "a.log").touch()
|
||||
Path(tmp_path / "a.txt").touch()
|
||||
Path(tmp_path / "a.csv").touch()
|
||||
Path(tmp_path / "a.py").touch()
|
||||
Path(tmp_path / "a").touch()
|
||||
Path(tmp_path / "a.pdf").touch()
|
||||
|
||||
# test
|
||||
assert is_log_file(Path(tmp_path / "a.log"))
|
||||
assert is_log_file(Path(tmp_path / "a.txt"))
|
||||
assert is_log_file(Path(tmp_path / "a")) # without extensions
|
||||
assert not is_log_file(Path(tmp_path / "a.csv"))
|
||||
assert not is_log_file(Path(tmp_path / "a.py"))
|
||||
assert not is_log_file(Path(tmp_path / "a.pdf"))
|
||||
|
||||
|
||||
def test_get_or_create_analyzed_folder_exists(make_mock_account, monkeypatch):
|
||||
@@ -9,14 +34,14 @@ def test_get_or_create_analyzed_folder_exists(make_mock_account, monkeypatch):
|
||||
Args:
|
||||
make_mock_account: Fake account owning the Logs folder
|
||||
monkeypatch: MonkeyPatch to generate test context
|
||||
|
||||
|
||||
"""
|
||||
existing_folder = MagicMock()
|
||||
account = make_mock_account(analyzed_folder=existing_folder)
|
||||
|
||||
fake_folder_cls = MagicMock()
|
||||
with monkeypatch.context() as m:
|
||||
m.setattr("logwatcher.mail_utils.Folder", fake_folder_cls)
|
||||
m.setattr("logwatcher.utils.Folder", fake_folder_cls)
|
||||
result = get_or_create_folder(account, "Analyzed")
|
||||
|
||||
assert result is existing_folder
|
||||
@@ -30,8 +55,8 @@ def test_get_or_create_analyzed_folder_creates(make_mock_account, monkeypatch):
|
||||
fake_folder_instance = MagicMock()
|
||||
fake_folder_cls = MagicMock(return_value=fake_folder_instance)
|
||||
with monkeypatch.context() as m:
|
||||
m.setattr("logwatcher.mail_utils.Folder", fake_folder_cls)
|
||||
m.setattr("logwatcher.utils.Folder", fake_folder_cls)
|
||||
result = get_or_create_folder(account, "Analyzed")
|
||||
|
||||
assert result is fake_folder_instance
|
||||
fake_folder_instance.save.assert_called_once()
|
||||
fake_folder_instance.save.assert_called_once()
|
||||
Reference in New Issue
Block a user