diff --git a/server/planning/assignments/assignments.py b/server/planning/assignments/assignments.py index 76790564a..f285f6f41 100644 --- a/server/planning/assignments/assignments.py +++ b/server/planning/assignments/assignments.py @@ -1195,7 +1195,7 @@ def on_delete(self, doc): """ Validate that we have a lock on the Assignment and it's associated Planning item """ - if doc.get("_to_delete") is True: + if doc.get("_to_delete") is True or not request: # Already marked for delete - no validation needed (could be the background job) return diff --git a/server/planning/commands/populate_planning_types_test.py b/server/planning/commands/populate_planning_types_test.py index 4f5b6d1a4..69185db37 100644 --- a/server/planning/commands/populate_planning_types_test.py +++ b/server/planning/commands/populate_planning_types_test.py @@ -11,7 +11,7 @@ import os import json -from superdesk.tests import TestCase +from planning.tests import TestCase from superdesk import get_resource_service from apps.prepopulate.app_populate import AppPopulateCommand diff --git a/server/planning/planning/planning.py b/server/planning/planning/planning.py index 8712345f6..fac3e8ad2 100644 --- a/server/planning/planning/planning.py +++ b/server/planning/planning/planning.py @@ -15,7 +15,7 @@ import logging from datetime import datetime -from flask import json, current_app as app +from flask import json, current_app as app, request from eve.methods.common import resolve_document_etag import superdesk @@ -1274,23 +1274,24 @@ def delete_assignments_for_coverages(self, coverages, notify=True): if original_assigment: assignment_service.system_update(ObjectId(assign_id), {"_to_delete": True}, original_assigment) - session_id = get_auth().get("_id") - user_id = get_user().get(config.ID_FIELD) - if len(deleted_assignments) > 0: - push_notification( - "assignments:delete", - items=deleted_assignments, - session=session_id, - user=user_id, - ) + if request: + session_id = get_auth().get("_id") + user_id = get_user().get(config.ID_FIELD) + if len(deleted_assignments) > 0: + push_notification( + "assignments:delete", + items=deleted_assignments, + session=session_id, + user=user_id, + ) - if len(failed_assignments) > 0 and notify: - push_notification( - "assignments:delete:fail", - items=failed_assignments, - session=session_id, - user=user_id, - ) + if len(failed_assignments) > 0 and notify: + push_notification( + "assignments:delete:fail", + items=failed_assignments, + session=session_id, + user=user_id, + ) def get_expired_items(self, expiry_datetime, spiked_planning_only=False): """Get the expired items diff --git a/server/planning/tests/__init__.py b/server/planning/tests/__init__.py index e6eabfa68..e4c29c2c5 100644 --- a/server/planning/tests/__init__.py +++ b/server/planning/tests/__init__.py @@ -3,6 +3,8 @@ class TestCase(_TestCase): + test_context = None # avoid using test_request_context + def setUp(self): config = {"INSTALLED_APPS": ["planning"]} update_config(config) diff --git a/server/planning/tests/ingest_cancelled_test.py b/server/planning/tests/ingest_cancelled_test.py new file mode 100644 index 000000000..ecdeffd64 --- /dev/null +++ b/server/planning/tests/ingest_cancelled_test.py @@ -0,0 +1,36 @@ +from flask import request +from planning.tests import TestCase +from planning.common import update_post_item + + +class IngestCancelledTestCase(TestCase): + def test_ingest_cancelled_event(self): + assert not request, request + + assignments = [ + {"planning_item": "p1", "coverage_item": "c1"}, + ] + + self.app.data.insert("assignments", assignments) + planning = { + "_id": "p1", + "name": "planning item", + "type": "planning", + "coverages": [ + { + "coverage_id": "c1", + "planning": {}, + "assigned_to": { + "assignment_id": assignments[0]["_id"], + }, + }, + ], + } + + self.app.data.insert("planning", [planning]) + + with self.app.app_context(): + update_post_item({"pubstatus": "cancelled"}, planning) + + cursor, count = self.app.data.find("assignments", req=None, lookup={}) + assert count == 0 diff --git a/server/planning/tests/output_formatters/file_providers_test.py b/server/planning/tests/output_formatters/file_providers_test.py index 75333a861..be0a7c624 100644 --- a/server/planning/tests/output_formatters/file_providers_test.py +++ b/server/planning/tests/output_formatters/file_providers_test.py @@ -12,7 +12,7 @@ from unittest import mock import hmac -from superdesk.tests import TestCase +from planning.tests import TestCase from superdesk.publish import TransmitterFileEntry from superdesk.publish.transmitters.ftp import FTPPublishService from superdesk.publish.transmitters.http_push import HTTPPushService diff --git a/server/planning/tests/output_formatters/json_event_test.py b/server/planning/tests/output_formatters/json_event_test.py index d71824e89..66a25f26c 100644 --- a/server/planning/tests/output_formatters/json_event_test.py +++ b/server/planning/tests/output_formatters/json_event_test.py @@ -2,7 +2,7 @@ import tempfile from unittest import mock -from superdesk.tests import TestCase +from planning.tests import TestCase from planning.output_formatters.json_event import JsonEventFormatter from planning.events import init_app from eve.methods.common import store_media_files diff --git a/server/planning/utils.py b/server/planning/utils.py index 0d24ac182..477749de1 100644 --- a/server/planning/utils.py +++ b/server/planning/utils.py @@ -4,6 +4,7 @@ from datetime import datetime from flask_babel import lazy_gettext from eve.utils import str_to_date +from superdesk.utc import utc_to_local import arrow from flask import current_app as app import pytz @@ -67,14 +68,18 @@ def parse_date(datetime: Union[str, datetime]) -> datetime: return datetime +def local_date(datetime: datetime, tz: pytz.BaseTzInfo) -> datetime: + return tz.normalize(parse_date(datetime).replace(tzinfo=pytz.utc).astimezone(tz)) + + def time_short(datetime: datetime, tz: pytz.BaseTzInfo): if datetime: - return parse_date(datetime).astimezone(tz).strftime(app.config.get("TIME_FORMAT_SHORT", "%H:%M")) + return local_date(datetime, tz).strftime(app.config.get("TIME_FORMAT_SHORT", "%H:%M")) def date_short(datetime: datetime, tz: pytz.BaseTzInfo): if datetime: - return parse_date(datetime).astimezone(tz).strftime(app.config.get("DATE_FORMAT_SHORT", "%d/%m/%Y")) + return local_date(datetime, tz).strftime(app.config.get("DATE_FORMAT_SHORT", "%d/%m/%Y")) def get_event_formatted_dates(event: Dict[str, Any]) -> str: