mirror of
https://github.com/Tech-Workers-Coalition-Italia/mobilizon-reshare.git
synced 2025-02-06 04:13:27 +01:00
recap header (#79)
* added basic recap feature (no error handling) * introduced abstractpublication * extracted base reports * added error report to recap * added test * added docs * implemented publisher and formatter * fixed API for recap * removed redundant config validation * added config sample * added active publisher test * added recap header template
This commit is contained in:
parent
71b65342b9
commit
489d41179e
@ -169,6 +169,13 @@ class AbstractEventFormatter(LoggerMixin, ConfLoaderMixin):
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_recap_header(self):
|
||||
template_path = (
|
||||
self.conf.recap_header_template_path
|
||||
or self.default_recap_header_template_path
|
||||
)
|
||||
return JINJA_ENV.get_template(template_path).render()
|
||||
|
||||
def get_recap_fragment_template(self) -> Template:
|
||||
template_path = (
|
||||
self.conf.recap_template_path or self.default_recap_template_path
|
||||
|
@ -176,7 +176,7 @@ class RecapCoordinator:
|
||||
for recap_publication in self.recap_publications:
|
||||
try:
|
||||
|
||||
fragments = []
|
||||
fragments = [recap_publication.formatter.get_recap_header()]
|
||||
for event in recap_publication.events:
|
||||
fragments.append(
|
||||
recap_publication.formatter.get_recap_fragment(event)
|
||||
|
@ -25,6 +25,10 @@ class TelegramFormatter(AbstractEventFormatter):
|
||||
"mobilizon_reshare.publishers.templates", "telegram_recap.tmpl.j2"
|
||||
)
|
||||
|
||||
default_recap_header_template_path = pkg_resources.resource_filename(
|
||||
"mobilizon_reshare.publishers.templates", "telegram_recap_header.tmpl.j2"
|
||||
)
|
||||
|
||||
_conf = ("publisher", "telegram")
|
||||
|
||||
@staticmethod
|
||||
|
@ -25,6 +25,10 @@ class TwitterFormatter(AbstractEventFormatter):
|
||||
"mobilizon_reshare.publishers.templates", "twitter_recap.tmpl.j2"
|
||||
)
|
||||
|
||||
default_recap_header_template_path = pkg_resources.resource_filename(
|
||||
"mobilizon_reshare.publishers.templates", "twitter_recap_header.tmpl.j2"
|
||||
)
|
||||
|
||||
def validate_event(self, event: MobilizonEvent) -> None:
|
||||
text = event.description
|
||||
if not (text and text.strip()):
|
||||
|
@ -29,6 +29,10 @@ class ZulipFormatter(AbstractEventFormatter):
|
||||
"mobilizon_reshare.publishers.templates", "zulip_recap.tmpl.j2"
|
||||
)
|
||||
|
||||
default_recap_header_template_path = pkg_resources.resource_filename(
|
||||
"mobilizon_reshare.publishers.templates", "zulip_recap_header.tmpl.j2"
|
||||
)
|
||||
|
||||
def validate_event(self, event: MobilizonEvent) -> None:
|
||||
text = event.description
|
||||
if not (text and text.strip()):
|
||||
|
@ -0,0 +1 @@
|
||||
Upcoming events
|
@ -0,0 +1 @@
|
||||
Upcoming events
|
@ -0,0 +1 @@
|
||||
Upcoming events
|
@ -1,3 +1,4 @@
|
||||
from collections import UserList
|
||||
from datetime import timedelta
|
||||
from uuid import UUID
|
||||
|
||||
@ -45,9 +46,21 @@ def mock_formatter_valid():
|
||||
def get_recap_fragment(self, event):
|
||||
return event.name
|
||||
|
||||
def get_recap_header(self):
|
||||
return "Upcoming"
|
||||
|
||||
return MockFormatter()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def message_collector():
|
||||
class MessageCollector(UserList):
|
||||
def collect_message(self, message):
|
||||
self.append(message)
|
||||
|
||||
return MessageCollector()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_formatter_invalid():
|
||||
class MockFormatter(AbstractEventFormatter):
|
||||
@ -64,10 +77,10 @@ def mock_formatter_invalid():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_publisher_valid():
|
||||
def mock_publisher_valid(message_collector):
|
||||
class MockPublisher(AbstractPlatform):
|
||||
def _send(self, message):
|
||||
pass
|
||||
message_collector.collect_message(message)
|
||||
|
||||
def _validate_response(self, response):
|
||||
pass
|
||||
@ -79,10 +92,11 @@ def mock_publisher_valid():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_publisher_invalid():
|
||||
def mock_publisher_invalid(message_collector):
|
||||
class MockPublisher(AbstractPlatform):
|
||||
def _send(self, message):
|
||||
pass
|
||||
|
||||
message_collector.collect_message(message)
|
||||
|
||||
def _validate_response(self, response):
|
||||
return InvalidResponse("error")
|
||||
@ -94,10 +108,10 @@ def mock_publisher_invalid():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_publisher_invalid_response():
|
||||
def mock_publisher_invalid_response(message_collector):
|
||||
class MockPublisher(AbstractPlatform):
|
||||
def _send(self, message):
|
||||
pass
|
||||
message_collector.collect_message(message)
|
||||
|
||||
def _validate_response(self, response):
|
||||
raise InvalidResponse("Invalid response")
|
||||
|
@ -155,8 +155,17 @@ async def test_notifier_coordinator_publication_failed(mock_publisher_valid):
|
||||
|
||||
@pytest.mark.parametrize("num_publications", [2])
|
||||
@pytest.mark.asyncio
|
||||
async def test_recap_coordinator_run_success(mock_recap_publications,):
|
||||
async def test_recap_coordinator_run_success(
|
||||
mock_recap_publications, message_collector
|
||||
):
|
||||
coordinator = RecapCoordinator(recap_publications=mock_recap_publications)
|
||||
report = coordinator.run()
|
||||
|
||||
# one recap per publication
|
||||
assert len(message_collector) == 2
|
||||
|
||||
# check that header is in all messages
|
||||
assert all(("Upcoming" in message) for message in message_collector)
|
||||
|
||||
assert len(report.reports) == 2
|
||||
assert report.successful, "\n".join(map(lambda rep: rep.reason, report.reports))
|
||||
|
Loading…
x
Reference in New Issue
Block a user