|
5 | 5 | from datetime import datetime, timezone |
6 | 6 |
|
7 | 7 | import pytest |
| 8 | +from django.db import transaction |
8 | 9 |
|
9 | 10 | from openedx_content import api |
10 | | -from openedx_content.applets.publishing.signals import LEARNING_PACKAGE_ENTITIES_CHANGED |
11 | | - |
12 | 11 | from tests.utils import capture_events |
13 | 12 |
|
14 | | -pytestmark = pytest.mark.django_db |
| 13 | +pytestmark = pytest.mark.django_db(transaction=True) |
15 | 14 | now_time = datetime.now(tz=timezone.utc) |
16 | 15 |
|
17 | 16 |
|
18 | | -def test_unbatched_events() -> None: |
| 17 | +class DeliberateRollbackException(Exception): |
| 18 | + """Exception used to deliberately cancel and roll back a DB transaction""" |
| 19 | + |
| 20 | + |
| 21 | +def test_single_entity_changed() -> None: |
19 | 22 | """ |
20 | 23 | Test that LEARNING_PACKAGE_ENTITIES_CHANGED is emitted when we change a |
21 | 24 | publishable entity. |
22 | 25 | """ |
23 | | - learning_package = api.create_learning_package(key="lp1", title="Test LP") |
| 26 | + learning_package = api.create_learning_package(key="lp1", title="Test LP 📦") |
24 | 27 |
|
25 | 28 | entity = api.create_publishable_entity(learning_package.id, key="entity1", created=now_time, created_by=None) |
26 | | - # create_publishable_entity_version also calls set_draft_version internally, so |
| 29 | + |
| 30 | + NEW_VERSION_NUM = 3 # Just for fun let's use a version number other than 1 |
| 31 | + |
27 | 32 | with capture_events(expected_count=1) as captured: |
28 | 33 | v1 = api.create_publishable_entity_version( |
29 | | - entity.id, version_num=1, title="Entity 1 V1", created=now_time, created_by=None |
| 34 | + entity.id, version_num=NEW_VERSION_NUM, title="Entity 1 V3", created=now_time, created_by=None |
30 | 35 | ) |
31 | 36 |
|
32 | 37 | entity.refresh_from_db() |
33 | 38 | assert api.get_draft_version(entity.id) == v1 |
34 | 39 |
|
35 | | - event = captured[0] |
36 | | - assert event.signal is LEARNING_PACKAGE_ENTITIES_CHANGED |
| 40 | + # Because only one change (create_..._version) has affected this version, it's easy for us to get its DraftChangeLog |
| 41 | + expected_draft_change_log_id = v1.draftchangelogrecord_set.get().draft_change_log_id |
| 42 | + |
| 43 | + event = captured[0] # capture_events(...) context manager already asserted there's only one event. |
| 44 | + assert event.signal is api.signals.LEARNING_PACKAGE_ENTITIES_CHANGED |
37 | 45 | assert event.kwargs["learning_package"].id == learning_package.id |
| 46 | + assert event.kwargs["learning_package"].title == "Test LP 📦" |
38 | 47 | assert event.kwargs["changed_by"].user_id is None |
39 | | - assert event.kwargs["change_log"].draft_change_log_id > 0 |
| 48 | + assert event.kwargs["change_log"].draft_change_log_id == expected_draft_change_log_id |
| 49 | + assert event.kwargs["change_log"].changes == [ |
| 50 | + api.signals.ChangeLogRecord(entity_id=entity.id, old_version=None, new_version=NEW_VERSION_NUM), |
| 51 | + ] |
40 | 52 | assert event.kwargs["metadata"].time == now_time |
| 53 | + |
| 54 | + |
| 55 | +def test_single_entity_changed_abort() -> None: |
| 56 | + """ |
| 57 | + Test that no events are emitted when we roll back a transaction that would have |
| 58 | + changed a publishable entity. |
| 59 | + """ |
| 60 | + learning_package = api.create_learning_package(key="lp1", title="Test LP 📦") |
| 61 | + |
| 62 | + entity = api.create_publishable_entity(learning_package.id, key="entity1", created=now_time, created_by=None) |
| 63 | + |
| 64 | + with capture_events(expected_count=0): |
| 65 | + try: |
| 66 | + with transaction.atomic(): |
| 67 | + api.create_publishable_entity_version( |
| 68 | + entity.id, version_num=1, title="Entity 1 V1", created=now_time, created_by=None |
| 69 | + ) |
| 70 | + raise DeliberateRollbackException() |
| 71 | + except DeliberateRollbackException: |
| 72 | + pass |
0 commit comments