Files
kleinanzeigen-bot/tests/smoke/test_smoke_health.py

104 lines
3.9 KiB
Python

# SPDX-FileCopyrightText: © Jens Bergmann and contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
# SPDX-ArtifactOfProjectHomePage: https://github.com/Second-Hand-Friends/kleinanzeigen-bot/
"""
Minimal smoke tests: post-deployment health checks for kleinanzeigen-bot.
These tests verify that the most essential components are operational.
"""
import logging
import subprocess # noqa: S404
import sys
from pathlib import Path
import pytest
from kleinanzeigen_bot.model.config_model import Config
from kleinanzeigen_bot.utils import i18n
from tests.conftest import DummyBrowser, DummyPage, SmokeKleinanzeigenBot
@pytest.mark.smoke
def test_app_starts(smoke_bot:SmokeKleinanzeigenBot) -> None:
"""Smoke: Bot can be instantiated and started without error."""
assert smoke_bot is not None
# Optionally call a minimal method if available
assert hasattr(smoke_bot, "run") or hasattr(smoke_bot, "login")
@pytest.mark.smoke
def test_config_loads() -> None:
"""Smoke: Minimal config loads successfully."""
minimal_cfg = {
"ad_defaults": {"contact": {"name": "dummy", "zipcode": "12345"}},
"login": {"username": "dummy", "password": "dummy"},
"publishing": {"delete_old_ads": "BEFORE_PUBLISH", "delete_old_ads_by_title": False},
}
config = Config.model_validate(minimal_cfg)
assert config.login.username == "dummy"
assert config.login.password == "dummy" # noqa: S105
@pytest.mark.smoke
def test_logger_initializes(tmp_path:Path, caplog:pytest.LogCaptureFixture) -> None:
"""Smoke: Logger can be initialized and used, robust to pytest log capture."""
log_path = tmp_path / "smoke_test.log"
logger_name = "smoke_test_logger_unique"
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)
logger.propagate = False
# Remove all handlers to start clean
for h in list(logger.handlers):
logger.removeHandler(h)
# Create and attach a file handler
handle = logging.FileHandler(str(log_path), encoding = "utf-8")
handle.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(levelname)s:%(name)s:%(message)s")
handle.setFormatter(formatter)
logger.addHandler(handle)
# Log a message
logger.info("Smoke test log message")
# Flush and close the handler
handle.flush()
handle.close()
# Remove the handler from the logger
logger.removeHandler(handle)
assert log_path.exists()
with open(log_path, "r", encoding = "utf-8") as f:
contents = f.read()
assert "Smoke test log message" in contents
@pytest.mark.smoke
def test_translation_system_healthy() -> None:
"""Smoke: Translation system loads and retrieves a known key."""
# Use a known string that should exist in translations (fallback to identity)
en = i18n.translate("Login", None)
assert isinstance(en, str)
assert len(en) > 0
# Switch to German and test
i18n.set_current_locale(i18n.Locale("de"))
de = i18n.translate("Login", None)
assert isinstance(de, str)
assert len(de) > 0
# Reset locale
i18n.set_current_locale(i18n.Locale("en"))
@pytest.mark.smoke
def test_dummy_browser_session() -> None:
"""Smoke: Dummy browser session can be created and closed."""
browser = DummyBrowser()
page = browser.page
assert isinstance(page, DummyPage)
browser.stop() # Should not raise
@pytest.mark.smoke
def test_cli_entrypoint_help_runs() -> None:
"""Smoke: CLI entry point runs with --help and exits cleanly (subprocess)."""
cli_module = "kleinanzeigen_bot.__main__"
result = subprocess.run([sys.executable, "-m", cli_module, "--help"], check = False, capture_output = True, text = True) # noqa: S603
assert result.returncode in {0, 1}, f"CLI exited with unexpected code: {result.returncode}\nstdout: {result.stdout}\nstderr: {result.stderr}"
assert "Usage" in result.stdout or "usage" in result.stdout or "help" in result.stdout.lower(), f"No help text in CLI output: {result.stdout}"