2021-12-05 16:43:23 +01:00
|
|
|
from logging import DEBUG, INFO
|
2021-11-11 15:18:04 +01:00
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
2022-07-12 07:39:56 +02:00
|
|
|
from mobilizon_reshare.config.command import CommandConfig
|
2022-02-23 17:26:13 +01:00
|
|
|
from mobilizon_reshare.storage.query.converter import event_from_model, event_to_model
|
2021-12-05 16:43:23 +01:00
|
|
|
from mobilizon_reshare.storage.query.read import get_all_events
|
2022-03-22 21:16:34 +01:00
|
|
|
from tests.commands.conftest import simple_event_element, second_event_element
|
2022-02-09 00:54:56 +01:00
|
|
|
from mobilizon_reshare.event.event import EventPublicationStatus
|
2021-11-11 15:18:04 +01:00
|
|
|
from mobilizon_reshare.main.start import start
|
|
|
|
from mobilizon_reshare.models.event import Event
|
|
|
|
from mobilizon_reshare.models.publication import PublicationStatus
|
|
|
|
|
2022-07-12 07:39:56 +02:00
|
|
|
one_published_event_specification = {
|
|
|
|
"event": 1,
|
|
|
|
"publications": [
|
|
|
|
{"event_idx": 0, "publisher_idx": 0, "status": PublicationStatus.COMPLETED}
|
|
|
|
],
|
|
|
|
"publisher": ["telegram", "twitter", "mastodon", "zulip"],
|
|
|
|
}
|
2022-03-22 21:16:34 +01:00
|
|
|
|
2021-11-11 15:18:04 +01:00
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
2022-07-12 07:39:56 +02:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"dry_run", [True, False]
|
|
|
|
) # the behavior should be identical with and without dry-run
|
2021-11-11 15:18:04 +01:00
|
|
|
@pytest.mark.parametrize(
|
2022-02-14 21:10:27 +01:00
|
|
|
"elements", [[]],
|
2021-11-11 15:18:04 +01:00
|
|
|
)
|
2021-11-11 16:20:50 +01:00
|
|
|
async def test_start_no_event(
|
2022-07-12 07:39:56 +02:00
|
|
|
mock_mobilizon_success_answer, mobilizon_answer, caplog, elements, dry_run
|
2021-11-11 16:20:50 +01:00
|
|
|
):
|
2021-11-11 15:18:04 +01:00
|
|
|
with caplog.at_level(DEBUG):
|
2022-07-12 07:39:56 +02:00
|
|
|
assert await start(CommandConfig(dry_run=dry_run)) is None
|
2021-11-11 15:18:04 +01:00
|
|
|
assert "No event to publish found" in caplog.text
|
|
|
|
|
|
|
|
|
2021-11-11 16:20:50 +01:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"publisher_class", [pytest.lazy_fixture("mock_publisher_class")]
|
|
|
|
)
|
2021-11-11 15:18:04 +01:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
@pytest.mark.parametrize(
|
2021-11-11 16:20:50 +01:00
|
|
|
"elements",
|
|
|
|
[[simple_event_element()], [simple_event_element(), simple_event_element()]],
|
2021-11-11 15:18:04 +01:00
|
|
|
)
|
|
|
|
async def test_start_new_event(
|
|
|
|
mock_mobilizon_success_answer,
|
|
|
|
mobilizon_answer,
|
|
|
|
caplog,
|
|
|
|
mock_publisher_config,
|
|
|
|
message_collector,
|
2021-12-05 16:43:23 +01:00
|
|
|
elements,
|
2022-07-12 07:39:56 +02:00
|
|
|
command_config,
|
2021-11-11 15:18:04 +01:00
|
|
|
):
|
|
|
|
with caplog.at_level(DEBUG):
|
2021-11-11 16:20:50 +01:00
|
|
|
# calling the start command
|
2022-07-12 07:39:56 +02:00
|
|
|
assert await start(command_config) is not None
|
2021-11-11 15:18:04 +01:00
|
|
|
|
2021-11-11 16:20:50 +01:00
|
|
|
# since the mobilizon_answer contains at least one result, one event to publish must be found and published
|
|
|
|
# by the publisher coordinator
|
2021-11-11 15:18:04 +01:00
|
|
|
assert "Event to publish found" in caplog.text
|
2021-11-11 16:20:50 +01:00
|
|
|
assert message_collector == [
|
|
|
|
"test event|Some description",
|
|
|
|
]
|
2021-11-11 15:18:04 +01:00
|
|
|
|
|
|
|
all_events = (
|
|
|
|
await Event.all()
|
|
|
|
.prefetch_related("publications")
|
|
|
|
.prefetch_related("publications__publisher")
|
|
|
|
)
|
|
|
|
|
2021-11-11 16:20:50 +01:00
|
|
|
# the start command should save all the events in the database
|
2021-12-05 16:43:23 +01:00
|
|
|
assert len(all_events) == len(elements), all_events
|
2021-11-11 15:18:04 +01:00
|
|
|
|
2021-11-11 16:20:50 +01:00
|
|
|
# it should create a publication for each publisher
|
2021-11-11 15:18:04 +01:00
|
|
|
publications = all_events[0].publications
|
2021-11-24 23:58:06 +01:00
|
|
|
assert len(publications) == 1, publications
|
2021-11-11 16:20:50 +01:00
|
|
|
|
|
|
|
# all the other events should have no publication
|
|
|
|
for e in all_events[1:]:
|
|
|
|
assert len(e.publications) == 0, e.publications
|
2021-11-11 15:18:04 +01:00
|
|
|
|
2021-11-11 16:20:50 +01:00
|
|
|
# all the publications for the first event should be saved as COMPLETED
|
|
|
|
for p in publications[1:]:
|
|
|
|
assert p.status == PublicationStatus.COMPLETED
|
|
|
|
|
|
|
|
# the derived status for the event should be COMPLETED
|
2022-07-12 07:39:56 +02:00
|
|
|
assert (
|
|
|
|
event_from_model(all_events[0]).status == EventPublicationStatus.COMPLETED
|
|
|
|
)
|
2021-11-11 16:20:50 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"publisher_class", [pytest.lazy_fixture("mock_publisher_class")]
|
|
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
2022-02-14 21:10:27 +01:00
|
|
|
"elements", [[]],
|
2021-11-11 16:20:50 +01:00
|
|
|
)
|
|
|
|
async def test_start_event_from_db(
|
|
|
|
mock_mobilizon_success_answer,
|
|
|
|
mobilizon_answer,
|
|
|
|
caplog,
|
|
|
|
mock_publisher_config,
|
|
|
|
message_collector,
|
|
|
|
event_generator,
|
2022-07-12 07:39:56 +02:00
|
|
|
command_config,
|
2021-11-11 16:20:50 +01:00
|
|
|
):
|
|
|
|
event = event_generator()
|
2022-02-23 17:26:13 +01:00
|
|
|
event_model = event_to_model(event)
|
2021-11-11 16:20:50 +01:00
|
|
|
await event_model.save()
|
|
|
|
|
|
|
|
with caplog.at_level(DEBUG):
|
|
|
|
# calling the start command
|
2022-07-12 07:39:56 +02:00
|
|
|
result = await start(command_config)
|
|
|
|
|
|
|
|
assert result.successful
|
|
|
|
assert len(result.reports) == 1
|
|
|
|
assert (
|
|
|
|
result.reports[0].published_content == "test event|description of the event"
|
|
|
|
)
|
2021-11-11 16:20:50 +01:00
|
|
|
|
|
|
|
# since the db contains at least one event, this has to be picked and published
|
|
|
|
assert "Event to publish found" in caplog.text
|
|
|
|
assert message_collector == [
|
|
|
|
"test event|description of the event",
|
|
|
|
]
|
|
|
|
|
|
|
|
await event_model.fetch_related("publications", "publications__publisher")
|
|
|
|
# it should create a publication for each publisher
|
|
|
|
publications = event_model.publications
|
2021-11-24 23:58:06 +01:00
|
|
|
assert len(publications) == 1, publications
|
2021-11-11 16:20:50 +01:00
|
|
|
|
|
|
|
# all the publications for the first event should be saved as COMPLETED
|
2021-11-24 23:58:06 +01:00
|
|
|
for p in publications:
|
2021-11-11 16:20:50 +01:00
|
|
|
assert p.status == PublicationStatus.COMPLETED
|
|
|
|
|
|
|
|
# the derived status for the event should be COMPLETED
|
2022-02-23 17:26:13 +01:00
|
|
|
assert event_from_model(event_model).status == EventPublicationStatus.COMPLETED
|
2021-11-11 16:20:50 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"publisher_class", [pytest.lazy_fixture("mock_publisher_invalid_class")]
|
|
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
2022-02-14 21:10:27 +01:00
|
|
|
"elements", [[]],
|
2021-11-11 16:20:50 +01:00
|
|
|
)
|
|
|
|
async def test_start_publisher_failure(
|
|
|
|
mock_mobilizon_success_answer,
|
|
|
|
mobilizon_answer,
|
|
|
|
caplog,
|
|
|
|
mock_publisher_config,
|
|
|
|
message_collector,
|
|
|
|
event_generator,
|
|
|
|
mock_notifier_config,
|
2022-07-12 07:39:56 +02:00
|
|
|
command_config,
|
2021-11-11 16:20:50 +01:00
|
|
|
):
|
|
|
|
event = event_generator()
|
2022-02-23 17:26:13 +01:00
|
|
|
event_model = event_to_model(event)
|
2021-11-11 16:20:50 +01:00
|
|
|
await event_model.save()
|
|
|
|
|
|
|
|
with caplog.at_level(DEBUG):
|
|
|
|
# calling the start command
|
2022-07-12 07:39:56 +02:00
|
|
|
result = await start(command_config)
|
|
|
|
|
|
|
|
assert not result.successful
|
|
|
|
assert len(result.reports) == 1
|
|
|
|
assert result.reports[0].published_content is None
|
2021-11-11 16:20:50 +01:00
|
|
|
|
|
|
|
# since the db contains at least one event, this has to be picked and published
|
|
|
|
|
|
|
|
await event_model.fetch_related("publications", "publications__publisher")
|
|
|
|
# it should create a publication for each publisher
|
|
|
|
publications = event_model.publications
|
2021-11-24 23:58:06 +01:00
|
|
|
assert len(publications) == 1, publications
|
2021-11-11 16:20:50 +01:00
|
|
|
|
|
|
|
# all the publications for event should be saved as FAILED
|
|
|
|
for p in publications:
|
|
|
|
assert p.status == PublicationStatus.FAILED
|
|
|
|
assert p.reason == "credentials error"
|
|
|
|
|
|
|
|
assert "Event to publish found" in caplog.text
|
|
|
|
assert message_collector == [
|
2021-11-24 23:58:06 +01:00
|
|
|
f"Publication {p.id} failed with status: 0."
|
2022-02-05 18:46:48 +01:00
|
|
|
f"\nReason: credentials error\nPublisher: mock\nEvent: test event"
|
2021-11-11 16:20:50 +01:00
|
|
|
for p in publications
|
|
|
|
for _ in range(2)
|
|
|
|
] # 2 publications failed * 2 notifiers
|
|
|
|
# the derived status for the event should be FAILED
|
2022-02-23 17:26:13 +01:00
|
|
|
assert event_from_model(event_model).status == EventPublicationStatus.FAILED
|
2021-12-05 16:43:23 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"publisher_class", [pytest.lazy_fixture("mock_publisher_class")]
|
|
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
2022-02-14 21:10:27 +01:00
|
|
|
"elements", [[second_event_element()]],
|
2021-12-05 16:43:23 +01:00
|
|
|
)
|
|
|
|
async def test_start_second_execution(
|
|
|
|
mock_mobilizon_success_answer,
|
|
|
|
mobilizon_answer,
|
|
|
|
caplog,
|
|
|
|
mock_publisher_config,
|
|
|
|
message_collector,
|
2022-07-12 07:39:56 +02:00
|
|
|
generate_models,
|
|
|
|
command_config,
|
2021-12-05 16:43:23 +01:00
|
|
|
):
|
2022-03-22 21:16:34 +01:00
|
|
|
await generate_models(one_published_event_specification)
|
2021-12-05 16:43:23 +01:00
|
|
|
|
|
|
|
# I clean the message collector
|
|
|
|
message_collector.data = []
|
|
|
|
|
|
|
|
with caplog.at_level(INFO):
|
|
|
|
# calling the start command
|
2022-07-12 07:39:56 +02:00
|
|
|
assert await start(command_config) is not None
|
2021-12-05 16:43:23 +01:00
|
|
|
|
|
|
|
# verify that the second event gets published
|
|
|
|
assert "Event to publish found" in caplog.text
|
|
|
|
assert message_collector == [
|
2022-03-22 21:16:34 +01:00
|
|
|
"event_1|desc_1",
|
2021-12-05 16:43:23 +01:00
|
|
|
]
|
|
|
|
# I verify that the db event and the new event coming from mobilizon are both in the db
|
|
|
|
assert len(list(await get_all_events())) == 2
|
2022-07-12 07:39:56 +02:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"publisher_class", [pytest.lazy_fixture("mock_publisher_class")]
|
|
|
|
)
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"elements",
|
|
|
|
[[simple_event_element()], [simple_event_element(), simple_event_element()]],
|
|
|
|
)
|
|
|
|
async def test_start_dry_run(
|
|
|
|
mock_mobilizon_success_answer,
|
|
|
|
mobilizon_answer,
|
|
|
|
caplog,
|
|
|
|
mock_publisher_config,
|
|
|
|
message_collector,
|
|
|
|
elements,
|
|
|
|
):
|
|
|
|
with caplog.at_level(DEBUG):
|
|
|
|
# calling the start command
|
|
|
|
result = await start(CommandConfig(dry_run=True))
|
|
|
|
assert result.successful
|
|
|
|
assert len(result.reports) == 1
|
|
|
|
assert result.reports[0].published_content == "test event|Some description"
|
|
|
|
|
|
|
|
assert "Event to publish found" in caplog.text
|
|
|
|
assert (
|
|
|
|
"Executing in dry run mode. No event is going to be published."
|
|
|
|
in caplog.text
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
message_collector == []
|
|
|
|
) # the configured publisher shouldn't be called if in dry run mode
|
|
|
|
|
|
|
|
all_events = (
|
|
|
|
await Event.all()
|
|
|
|
.prefetch_related("publications")
|
|
|
|
.prefetch_related("publications__publisher")
|
|
|
|
)
|
|
|
|
|
|
|
|
# the start command should save all the events in the database
|
|
|
|
assert len(all_events) == len(elements), all_events
|
|
|
|
|
|
|
|
# it should create no publication
|
|
|
|
publications = all_events[0].publications
|
|
|
|
assert len(publications) == 0, publications
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"publisher_class", [pytest.lazy_fixture("mock_publisher_class")]
|
|
|
|
)
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"elements",
|
|
|
|
[[simple_event_element()], [simple_event_element(), simple_event_element()]],
|
|
|
|
)
|
|
|
|
async def test_start_dry_run_second_execution(
|
|
|
|
mock_mobilizon_success_answer,
|
|
|
|
mobilizon_answer,
|
|
|
|
caplog,
|
|
|
|
mock_publisher_config,
|
|
|
|
message_collector,
|
|
|
|
elements,
|
|
|
|
):
|
|
|
|
with caplog.at_level(DEBUG):
|
|
|
|
# calling the start command in dry_run
|
|
|
|
assert await start(CommandConfig(dry_run=True)) is not None
|
|
|
|
|
|
|
|
assert "Event to publish found" in caplog.text
|
|
|
|
assert (
|
|
|
|
"Executing in dry run mode. No event is going to be published."
|
|
|
|
in caplog.text
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
message_collector == []
|
|
|
|
) # the configured publisher shouldn't be called if in dry run mode
|
|
|
|
|
|
|
|
# calling the start command in normal mode
|
|
|
|
assert await start(CommandConfig(dry_run=False)) is not None
|
|
|
|
assert message_collector == [
|
|
|
|
"test event|Some description"
|
|
|
|
] # the publisher should now have published one message
|
|
|
|
all_events = (
|
|
|
|
await Event.all()
|
|
|
|
.prefetch_related("publications")
|
|
|
|
.prefetch_related("publications__publisher")
|
|
|
|
)
|
|
|
|
|
|
|
|
# verify that the dry run doesn't mistakenly does double saves
|
|
|
|
assert len(all_events) == len(elements), all_events
|