feat: implement rss generation (#130)

This commit is contained in:
2024-08-29 16:53:40 +03:00
parent d7c4fccf98
commit 529d4caa0e
18 changed files with 481 additions and 28 deletions

View File

@ -75,6 +75,7 @@ def test_schema(configuration: Configuration) -> None:
assert schema.pop("remote-push")
assert schema.pop("remote-service")
assert schema.pop("report")
assert schema.pop("rss")
assert schema.pop("rsync")
assert schema.pop("s3")
assert schema.pop("telegram")

View File

@ -3,6 +3,7 @@ import pytest
from ahriman.core.configuration import Configuration
from ahriman.core.report.email import Email
from ahriman.core.report.remote_call import RemoteCall
from ahriman.core.report.rss import RSS
from ahriman.core.report.telegram import Telegram
@ -15,7 +16,7 @@ def email(configuration: Configuration) -> Email:
configuration(Configuration): configuration fixture
Returns:
RemoteCall: email trigger test instance
Email: email trigger test instance
"""
_, repository_id = configuration.check_loaded()
return Email(repository_id, configuration, "email")
@ -38,6 +39,21 @@ def remote_call(configuration: Configuration) -> RemoteCall:
return RemoteCall(repository_id, configuration, "remote-call")
@pytest.fixture
def rss(configuration: Configuration) -> RSS:
"""
fixture for rss trigger
Args:
configuration(Configuration): configuration fixture
Returns:
RSS: rss trigger test instance
"""
_, repository_id = configuration.check_loaded()
return RSS(repository_id, configuration, "rss")
@pytest.fixture
def telegram(configuration: Configuration) -> Telegram:
"""
@ -47,7 +63,7 @@ def telegram(configuration: Configuration) -> Telegram:
configuration(Configuration): configuration fixture
Returns:
RemoteCall: telegram trigger test instance
Telegram: telegram trigger test instance
"""
_, repository_id = configuration.check_loaded()
return Telegram(repository_id, configuration, "telegram")

View File

@ -1,9 +1,24 @@
from ahriman.core.configuration import Configuration
from ahriman.core.report.jinja_template import JinjaTemplate
from ahriman.core.utils import utcnow
from ahriman.models.package import Package
from ahriman.models.result import Result
def test_format_datetime() -> None:
"""
must format datetime
"""
assert JinjaTemplate.format_datetime(utcnow())
def sort_content() -> None:
"""
must sort content for the template
"""
assert JinjaTemplate.sort_content([{"filename": "2"}, {"filename": "1"}]) == [{"filename": "1"}, {"filename": "2"}]
def test_generate(configuration: Configuration, package_ahriman: Package) -> None:
"""
must generate html report

View File

@ -78,6 +78,17 @@ def test_report_remote_call(configuration: Configuration, result: Result, mocker
report_mock.assert_called_once_with([], result)
def test_report_rss(configuration: Configuration, result: Result, mocker: MockerFixture) -> None:
"""
must instantiate rss trigger
"""
report_mock = mocker.patch("ahriman.core.report.rss.RSS.generate")
_, repository_id = configuration.check_loaded()
Report.load(repository_id, configuration, "rss").run(result, [])
report_mock.assert_called_once_with([], result)
def test_report_telegram(configuration: Configuration, result: Result, mocker: MockerFixture) -> None:
"""
must generate telegram report

View File

@ -0,0 +1,79 @@
import pytest
from email.utils import parsedate_to_datetime
from pytest_mock import MockerFixture
from unittest.mock import MagicMock
from ahriman.core.report.rss import RSS
from ahriman.core.status import Client
from ahriman.core.utils import utcnow
from ahriman.models.event import Event, EventType
from ahriman.models.package import Package
from ahriman.models.result import Result
def test_format_datetime() -> None:
"""
must format timestamp to rfc format
"""
timestamp = utcnow().replace(microsecond=0)
assert parsedate_to_datetime(RSS.format_datetime(timestamp.timestamp())) == timestamp
def test_format_datetime_datetime() -> None:
"""
must format datetime to rfc format
"""
timestamp = utcnow().replace(microsecond=0)
assert parsedate_to_datetime(RSS.format_datetime(timestamp)) == timestamp
def test_format_datetime_empty() -> None:
"""
must generate empty string from None timestamp
"""
assert RSS.format_datetime(None) == ""
def test_sort_content() -> None:
"""
must sort content for the template
"""
assert RSS.sort_content([
{"filename": "2", "build_date": "Thu, 29 Aug 2024 16:36:55 -0000"},
{"filename": "1", "build_date": "Thu, 29 Aug 2024 16:36:54 -0000"},
{"filename": "3", "build_date": "Thu, 29 Aug 2024 16:36:56 -0000"},
]) == [
{"filename": "3", "build_date": "Thu, 29 Aug 2024 16:36:56 -0000"},
{"filename": "2", "build_date": "Thu, 29 Aug 2024 16:36:55 -0000"},
{"filename": "1", "build_date": "Thu, 29 Aug 2024 16:36:54 -0000"},
]
def test_content(rss: RSS, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must generate RSS content correctly
"""
client_mock = MagicMock()
client_mock.event_get.return_value = [
Event(EventType.PackageUpdated, package_ahriman.base),
Event(EventType.PackageUpdated, "random"),
Event(EventType.PackageUpdated, package_ahriman.base),
]
context_mock = mocker.patch("ahriman.core._Context.get", return_value=client_mock)
assert rss.content([package_ahriman]).success == [package_ahriman]
context_mock.assert_called_once_with(Client)
client_mock.event_get.assert_called_once_with(EventType.PackageUpdated, None, limit=rss.max_entries)
def test_generate(rss: RSS, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must generate report
"""
content_mock = mocker.patch("ahriman.core.report.rss.RSS.content", return_value=Result())
write_mock = mocker.patch("pathlib.Path.write_text")
rss.generate([package_ahriman], Result())
content_mock.assert_called_once_with([package_ahriman])
write_mock.assert_called_once_with(pytest.helpers.anyvar(int), encoding="utf8")

View File

@ -489,6 +489,7 @@ def test_walk(resource_path_root: Path) -> None:
resource_path_root / "web" / "templates" / "email-index.jinja2",
resource_path_root / "web" / "templates" / "error.jinja2",
resource_path_root / "web" / "templates" / "repo-index.jinja2",
resource_path_root / "web" / "templates" / "rss.jinja2",
resource_path_root / "web" / "templates" / "shell",
resource_path_root / "web" / "templates" / "telegram-index.jinja2",
])

View File

@ -24,6 +24,9 @@ def test_from_option_valid() -> None:
assert ReportSettings.from_option("telegram") == ReportSettings.Telegram
assert ReportSettings.from_option("TElegraM") == ReportSettings.Telegram
assert ReportSettings.from_option("rss") == ReportSettings.RSS
assert ReportSettings.from_option("RSS") == ReportSettings.RSS
assert ReportSettings.from_option("remote-call") == ReportSettings.RemoteCall
assert ReportSettings.from_option("reMOte-cALL") == ReportSettings.RemoteCall
assert ReportSettings.from_option("ahriman") == ReportSettings.RemoteCall

View File

@ -81,6 +81,13 @@ templates = ../web/templates
[remote-call]
manual = yes
[rss]
path =
homepage =
link_path =
template = rss.jinja2
templates = ../web/templates
[telegram]
api_key = apikey
chat_id = @ahrimantestchat