def test_ctasks_notifs_generator_daily_digest(self): """Test cycle tasks notifications generation job.""" with freeze_time("2015-05-01 14:29:00"): self.assert_notifications_for_object(self.cycle, "manual_cycle_created") self.assert_notifications_for_object(self.ctask, "manual_cycle_created", "cycle_task_due_in", "cycle_task_due_today", "cycle_task_overdue") # Move task to Finished self.wf_generator.modify_object( self.ctask, data={"status": "Verified"}) generate_cycle_tasks_notifs() self.assert_notifications_for_object(self.cycle, "all_cycle_tasks_completed", "manual_cycle_created") # Undo finish self.wf_generator.modify_object( self.ctask, data={"status": "In Progress"}) generate_cycle_tasks_notifs() self.assert_notifications_for_object(self.cycle, "manual_cycle_created") self.assert_notifications_for_object(self.ctask, "cycle_task_due_in", "cycle_task_due_today", "cycle_task_overdue") self.wf_generator.modify_object( self.ctask, data={"status": "Declined"}) self.assert_notifications_for_object(self.ctask, "cycle_task_due_in", "cycle_task_due_today", "cycle_task_overdue", "cycle_task_declined")
def test_multi_all_tasks_finished_notification_created(self): with freeze_time("2015-05-01 13:20:34"): _, workflow = self.wf_generator.generate_workflow( self.one_time_workflow_2) _, cycle = self.wf_generator.generate_cycle(workflow) self.wf_generator.activate_workflow(workflow) cycle = Cycle.query.get(cycle.id) task1 = CycleTaskGroupObjectTask.query.get( cycle.cycle_task_group_object_tasks[0].id) self.task_change_status(task1) generate_cycle_tasks_notifs() notif = db.session.query(Notification).filter(and_( Notification.object_id == cycle.id, Notification.object_type == cycle.type, Notification.sent_at == None, # noqa Notification.notification_type == self.get_notification_type( "all_cycle_tasks_completed" ) )).all() # there is still one task in the cycle, so there should be no # notifications for all tasks completed self.assertEqual(notif, []) notif = db.session.query(Notification).filter(and_( Notification.object_id == task1.id, Notification.object_type == task1.type, Notification.sent_at == None, # noqa Notification.notification_type != self.get_notification_type( "all_cycle_tasks_completed" ) )).all() # The task was verified, so there should be no notifications left for due # dates. self.assertEqual(notif, []) task2 = CycleTaskGroupObjectTask.query.get( cycle.cycle_task_group_object_tasks[1].id) self.task_change_status(task2) generate_cycle_tasks_notifs() notif = db.session.query(Notification).filter(and_( Notification.object_id == cycle.id, Notification.object_type == cycle.type, Notification.sent_at == None, # noqa Notification.notification_type == self.get_notification_type( "all_cycle_tasks_completed" ) )).all() self.assertEqual(len(notif), 1, "notifications: {}".format(str(notif)))
def test_ctasks_notifs_generator_cron_job(self): """Test cycle tasks notifications generation cron job.""" with freeze_time("2015-05-2 08:00:00"): generate_cycle_tasks_notifs() self.assert_notifications_for_object(self.cycle, "manual_cycle_created") self.assert_notifications_for_object(self.ctask, "manual_cycle_created", "cycle_task_due_in", "cycle_task_due_today", "cycle_task_overdue")
def test_adjust_overdue_notifications_on_task_status_change(self, is_vf_needed, _): """Sending overdue notifications should take task status into account.""" with freeze_time("2017-05-15 14:25:36"): tmp = self.one_time_workflow.copy() tmp['is_verification_needed'] = is_vf_needed _, workflow = self.wf_generator.generate_workflow(tmp) self.wf_generator.generate_cycle(workflow) response, workflow = self.wf_generator.activate_workflow(workflow) self.assert200(response) tasks = workflow.cycles[0].cycle_task_group_object_tasks task1, task2 = tasks self.wf_generator.modify_object(task2, {"end_date": date(2099, 12, 31)}) user = models.Person.query.get(self.user.id) user_email = user.email if is_vf_needed: non_final_states = [CycleTaskGroupObjectTask.ASSIGNED, CycleTaskGroupObjectTask.IN_PROGRESS, CycleTaskGroupObjectTask.FINISHED, CycleTaskGroupObjectTask.DECLINED] final_state = CycleTaskGroupObjectTask.VERIFIED else: non_final_states = [CycleTaskGroupObjectTask.ASSIGNED, CycleTaskGroupObjectTask.IN_PROGRESS] final_state = CycleTaskGroupObjectTask.FINISHED with freeze_time("2017-05-16 08:09:10"): # a day after task1 due date for state in non_final_states: # clear all notifications before before changing the task status models.Notification.query.delete() _, notif_data = common.get_daily_notifications() self.assertEqual(notif_data, {}) self.wf_generator.modify_object(task1, {"status": state}) _, notif_data = common.get_daily_notifications() user_notifs = notif_data.get(user_email, {}) self.assertIn("task_overdue", user_notifs) self.assertEqual(len(user_notifs["task_overdue"]), 1) # WITHOUT clearing the overdue notifications, move the task to "verified" # state, and the overdue notification should disappear. self.wf_generator.modify_object(task1, {"status": final_state}) common.generate_cycle_tasks_notifs() _, notif_data = common.get_daily_notifications() user_notifs = notif_data.get(user_email, {}) self.assertNotIn("task_overdue", user_notifs)
def test_cycle_task_update_timelines(self, _datetime, notifications): """Test cycle task has been updated: 1) the day before job is called; 2) the same day job is called before 08:00 AM UTC; 3) the same day job is called after 08:00 AM UTC; 4) two days before job is called. """ with freeze_time("2015-05-01 14:29:00"): # Move task to Finished self.wf_generator.modify_object( self.ctask, data={"status": "Verified"}) with freeze_time(_datetime): generate_cycle_tasks_notifs() self.assert_notifications_for_object(self.cycle, *notifications)
def test_propagation_status_short(self): """Task status propagation for not required verification workflow.""" all_models.Cycle.query.filter( all_models.Cycle.id == self.cycle.id ).update({ all_models.Cycle.is_verification_needed: False }) db.session.commit() self.tasks = all_models.CycleTaskGroupObjectTask.query.order_by( all_models.CycleTaskGroupObjectTask.id ).all() # all tasks in assigned state self.assertEqual([self.ASSIGNED] * 3, [t.status for t in self.tasks]) # all tasks in progress state self.assert_status_over_bulk_update([self.IN_PROGRESS] * 3, [self.IN_PROGRESS] * 3) self.assertEqual(self.IN_PROGRESS, self.group.status) self.assertEqual(self.IN_PROGRESS, self.cycle.status) self.assertEqual(all_models.Workflow.ACTIVE, self.workflow.status) # update 1 task to finished self.assert_status_over_bulk_update( [self.FINISHED], [self.FINISHED, self.IN_PROGRESS, self.IN_PROGRESS]) self.assertEqual(self.IN_PROGRESS, self.group.status) self.assertEqual(self.IN_PROGRESS, self.cycle.status) self.assertEqual(all_models.Workflow.ACTIVE, self.workflow.status) generate_cycle_tasks_notifs() self.assert_notifications_for_object(self.tasks[0]) for task in self.tasks[1:]: self.assert_notifications_for_object(task, u'cycle_task_due_in', u'cycle_task_due_today', u'cycle_task_overdue', u'manual_cycle_created') self.cycle = self.tasks[0].cycle self.assert_notifications_for_object(self.cycle, u'manual_cycle_created') # all tasks moved to finished self.assert_status_over_bulk_update([self.FINISHED] * 3, [self.FINISHED] * 3) self.assertEqual(self.FINISHED, self.group.status) self.assertEqual(self.FINISHED, self.cycle.status) self.assertEqual(all_models.Workflow.INACTIVE, self.workflow.status) generate_cycle_tasks_notifs() for task in self.tasks: self.assert_notifications_for_object(task) self.cycle = self.tasks[0].cycle self.assert_notifications_for_object(self.cycle, u"all_cycle_tasks_completed", u'manual_cycle_created')
def test_propagation_status_full(self): """Task status propagation for required verification workflow.""" # all tasks in assigned state self.assertEqual([self.ASSIGNED] * 3, [t.status for t in self.tasks]) # all tasks in progress state self.assert_status_over_bulk_update([self.IN_PROGRESS] * 3, [self.IN_PROGRESS] * 3) self.assertEqual(self.IN_PROGRESS, self.group.status) self.assertEqual(self.IN_PROGRESS, self.cycle.status) self.assertEqual(all_models.Workflow.ACTIVE, self.workflow.status) # update 1 task to finished self.assert_status_over_bulk_update( [self.FINISHED], [self.FINISHED, self.IN_PROGRESS, self.IN_PROGRESS]) self.assertEqual(self.IN_PROGRESS, self.group.status) self.assertEqual(self.IN_PROGRESS, self.cycle.status) self.assertEqual(all_models.Workflow.ACTIVE, self.workflow.status) # all tasks moved to finished self.assert_status_over_bulk_update([self.FINISHED] * 3, [self.FINISHED] * 3) self.assertEqual(self.FINISHED, self.group.status) self.assertEqual(self.FINISHED, self.cycle.status) self.assertEqual(all_models.Workflow.ACTIVE, self.workflow.status) for task in self.tasks: self.assert_notifications_for_object(task, u'cycle_task_due_in', u'cycle_task_due_today', u'cycle_task_overdue', u'manual_cycle_created') self.cycle = self.tasks[0].cycle self.assert_notifications_for_object(self.cycle, u'manual_cycle_created') # all tasks moved to verified self.assert_status_over_bulk_update([self.VERIFIED] * 3, [self.VERIFIED] * 3) self.assertEqual(self.VERIFIED, self.group.status) self.assertEqual(self.VERIFIED, self.cycle.status) self.assertEqual(all_models.Workflow.INACTIVE, self.workflow.status) generate_cycle_tasks_notifs() for task in self.tasks: self.assert_notifications_for_object(task) self.cycle = self.tasks[0].cycle self.assert_notifications_for_object(self.cycle, u"all_cycle_tasks_completed", u'manual_cycle_created')
def test_multi_all_tasks_finished_notification_created(self): """Test several all task completed notifications""" with freeze_time("2015-05-01 13:20:34"): _, workflow = self.wf_generator.generate_workflow( self.one_time_workflow_2) _, cycle = self.wf_generator.generate_cycle(workflow) self.wf_generator.activate_workflow(workflow) cycle = Cycle.query.get(cycle.id) task1 = CycleTaskGroupObjectTask.query.get( cycle.cycle_task_group_object_tasks[0].id) self.task_change_status(task1) generate_cycle_tasks_notifs() notif = self.get_notifications_by_type( cycle, "all_cycle_tasks_completed") # there is still one task in the cycle, so there should be no # notifications for all tasks completed self.assertEqual(notif, []) notif = self.get_notifications_by_type( task1, "all_cycle_tasks_completed") # The task was verified, so there should be no notifications left for due # dates. self.assertEqual(notif, []) task2 = CycleTaskGroupObjectTask.query.get( cycle.cycle_task_group_object_tasks[1].id) self.task_change_status(task2) generate_cycle_tasks_notifs() notif = self.get_notifications_by_type( cycle, "all_cycle_tasks_completed") self.assertEqual(len(notif), 1, "notifications: {}".format(str(notif)))
def test_single_task_accepted(self, mock_mail): """Test moving the end date to the future on accepted task. It is done before due_in and due_today notifications have been sent. """ with freeze_time("2015-05-01"): _, workflow = self.wf_generator.generate_workflow( self.one_time_workflow_1) _, cycle = self.wf_generator.generate_cycle(workflow) self.wf_generator.activate_workflow(workflow) with freeze_time("2015-05-02"): common.send_daily_digest_notifications() cycle = Cycle.query.get(cycle.id) task1 = CycleTaskGroupObjectTask.query.get( cycle.cycle_task_group_object_tasks[0].id) self.task_change_status(task1, "Finished") _, notif_data = common.get_daily_notifications() self.assertEqual(notif_data, {}) task_assignees = [self.user, self.secondary_assignee] with freeze_time("2015-05-03 13:20:34"): cycle = Cycle.query.get(cycle.id) task1 = CycleTaskGroupObjectTask.query.get( cycle.cycle_task_group_object_tasks[0].id) self.task_change_status(task1) generate_cycle_tasks_notifs() _, notif_data = common.get_daily_notifications() for user in task_assignees: self.assertNotIn(user.email, notif_data) self.assertIn("all_tasks_completed", notif_data["*****@*****.**"])
def test_ctasks_notifs_generator_daily_digest(self): """Test cycle tasks notifications generation job.""" with freeze_time("2015-05-01 14:29:00"): self.assert_notifications_for_object(self.cycle, "manual_cycle_created") self.assert_notifications_for_object(self.ctask, "manual_cycle_created", "cycle_task_due_in", "cycle_task_due_today", "cycle_task_overdue") # Move task to Finished self.wf_generator.modify_object(self.ctask, data={"status": "Verified"}) generate_cycle_tasks_notifs() self.assert_notifications_for_object(self.cycle, "all_cycle_tasks_completed", "manual_cycle_created") # Undo finish self.wf_generator.modify_object(self.ctask, data={"status": "In Progress"}) generate_cycle_tasks_notifs() self.assert_notifications_for_object(self.cycle, "manual_cycle_created") self.assert_notifications_for_object(self.ctask, "cycle_task_due_in", "cycle_task_due_today", "cycle_task_overdue") self.wf_generator.modify_object(self.ctask, data={"status": "Declined"}) self.assert_notifications_for_object(self.ctask, "cycle_task_due_in", "cycle_task_due_today", "cycle_task_overdue", "cycle_task_declined")
def test_single_task_accepted(self, mock_mail): """Test moving the end date to the future on accepted task. It is done before due_in and due_today notifications have been sent. """ with freeze_time("2015-05-01"): _, workflow = self.wf_generator.generate_workflow( self.one_time_workflow_1) _, cycle = self.wf_generator.generate_cycle(workflow) self.wf_generator.activate_workflow(workflow) with freeze_time("2015-05-02"): common.send_daily_digest_notifications() cycle = Cycle.query.get(cycle.id) task1 = CycleTaskGroupObjectTask.query.get( cycle.cycle_task_group_object_tasks[0].id) self.task_change_status(task1, "Finished") _, notif_data = common.get_daily_notifications() self.assertEqual(notif_data, {}) with freeze_time("2015-05-03 13:20:34"): cycle = Cycle.query.get(cycle.id) task1 = CycleTaskGroupObjectTask.query.get( cycle.cycle_task_group_object_tasks[0].id) self.task_change_status(task1) generate_cycle_tasks_notifs() user = Person.query.get(self.user.id) _, notif_data = common.get_daily_notifications() self.assertNotIn(user.email, notif_data) self.assertIn("all_tasks_completed", notif_data["*****@*****.**"])
def test_all_tasks_finished_notification_created(self): with freeze_time("2015-05-01 13:20:34"): _, workflow = self.wf_generator.generate_workflow( self.one_time_workflow_1) _, cycle = self.wf_generator.generate_cycle(workflow) self.wf_generator.activate_workflow(workflow) cycle = Cycle.query.get(cycle.id) task1 = CycleTaskGroupObjectTask.query.get( cycle.cycle_task_group_object_tasks[0].id) self.task_change_status(task1) generate_cycle_tasks_notifs() notif = db.session.query(Notification).filter(and_( Notification.object_id == cycle.id, Notification.object_type == cycle.type, Notification.sent_at == None, # noqa Notification.notification_type == self.get_notification_type( "all_cycle_tasks_completed" ) )).all() self.assertEqual(len(notif), 1, "notifications: {}".format(str(notif))) notif = db.session.query(Notification).filter(and_( Notification.object_id == task1.id, Notification.object_type == task1.type, Notification.sent_at == None, # noqa Notification.notification_type != self.get_notification_type( "all_cycle_tasks_completed" ) )).all() self.assertEqual(notif, [])
def test_all_tasks_finished_notification_created(self): with freeze_time("2015-05-01 13:20:34"): _, workflow = self.wf_generator.generate_workflow( self.one_time_workflow_1) _, cycle = self.wf_generator.generate_cycle(workflow) self.wf_generator.activate_workflow(workflow) cycle = Cycle.query.get(cycle.id) task1 = CycleTaskGroupObjectTask.query.get( cycle.cycle_task_group_object_tasks[0].id) self.task_change_status(task1) generate_cycle_tasks_notifs() notif = db.session.query(Notification).filter(and_( Notification.object_id == cycle.id, Notification.object_type == cycle.type, Notification.sent_at == None, # noqa Notification.notification_type == self.get_notification_type( "all_cycle_tasks_completed" ) )).all() self.assertEqual(len(notif), 1, "notifications: {}".format(str(notif))) notif = db.session.query(Notification).filter(and_( Notification.object_id == task1.id, Notification.object_type == task1.type, Notification.sent_at == None, # noqa Notification.notification_type != self.get_notification_type( "all_cycle_tasks_completed" ) )).all() self.assertEqual(notif, [])
def test_ctasks_notifs_generator_daily_digest_called_twice(self): """No duplicated notifications should be generated""" with freeze_time("2015-05-01 14:29:00"): generate_cycle_tasks_notifs(date(2015, 5, 1)) self.assert_notifications_for_object(self.cycle, "manual_cycle_created") self.assert_notifications_for_object(self.ctask, "manual_cycle_created", "cycle_task_due_in", "cycle_task_due_today", "cycle_task_overdue") # Move task to Finished self.wf_generator.modify_object( self.ctask, data={"status": "Verified"}) generate_cycle_tasks_notifs(date(2015, 5, 1)) generate_cycle_tasks_notifs(date(2015, 5, 1)) self.assert_notifications_for_object(self.cycle, "all_cycle_tasks_completed", "manual_cycle_created")
def test_ctasks_notifs_generator_daily_digest_called_twice(self): """No duplicated notifications should be generated""" with freeze_time("2015-05-01 14:29:00"): generate_cycle_tasks_notifs() self.assert_notifications_for_object(self.cycle, "manual_cycle_created") self.assert_notifications_for_object(self.ctask, "manual_cycle_created", "cycle_task_due_in", "cycle_task_due_today", "cycle_task_overdue") # Move task to Finished self.wf_generator.modify_object( self.ctask, data={"status": "Verified"}) generate_cycle_tasks_notifs() generate_cycle_tasks_notifs() self.assert_notifications_for_object(self.cycle, "all_cycle_tasks_completed", "manual_cycle_created")
def test_update_tasks_from_2_cycles(self): """Test bulk update few cycles at the same time.""" with factories.single_commit(): _, _, group, _ = self._create_cycle_structure() group_id = group.id all_models.Cycle.query.update( {all_models.Cycle.is_verification_needed: False}) db.session.commit() self.tasks = all_models.CycleTaskGroupObjectTask.query.order_by( all_models.CycleTaskGroupObjectTask.id).all() # all tasks in assigned state self.assertEqual([self.ASSIGNED] * 6, [t.status for t in self.tasks]) # all tasks in progress state self.assert_status_over_bulk_update([self.IN_PROGRESS] * 6, [self.IN_PROGRESS] * 6) group = all_models.CycleTaskGroup.query.get(group_id) self.assertEqual(self.IN_PROGRESS, self.group.status) self.assertEqual(self.IN_PROGRESS, group.status) self.assertEqual(self.IN_PROGRESS, self.cycle.status) self.assertEqual(self.IN_PROGRESS, group.cycle.status) self.assertEqual(all_models.Workflow.ACTIVE, self.workflow.status) self.assertEqual(all_models.Workflow.ACTIVE, group.cycle.workflow.status) # update 1 task to finished self.assert_status_over_bulk_update([self.FINISHED], [self.FINISHED] + [self.IN_PROGRESS] * 5) group = all_models.CycleTaskGroup.query.get(group_id) self.assertEqual(self.IN_PROGRESS, self.group.status) self.assertEqual(self.IN_PROGRESS, group.status) self.assertEqual(self.IN_PROGRESS, self.cycle.status) self.assertEqual(self.IN_PROGRESS, group.cycle.status) self.assertEqual(all_models.Workflow.ACTIVE, self.workflow.status) self.assertEqual(all_models.Workflow.ACTIVE, group.cycle.workflow.status) generate_cycle_tasks_notifs() self.assert_notifications_for_object(self.tasks[0]) for task in self.tasks[1:]: self.assert_notifications_for_object(task, u'cycle_task_due_in', u'cycle_task_due_today', u'cycle_task_overdue', u'manual_cycle_created') self.assert_notifications_for_object(self.group.cycle, u'manual_cycle_created') self.assert_notifications_for_object(group.cycle, u'manual_cycle_created') # all tasks moved to finished self.assert_status_over_bulk_update([self.FINISHED] * 6, [self.FINISHED] * 6) group = all_models.CycleTaskGroup.query.get(group_id) self.assertEqual(self.FINISHED, self.group.status) self.assertEqual(self.FINISHED, group.status) self.assertEqual(self.FINISHED, self.cycle.status) self.assertEqual(self.FINISHED, group.cycle.status) self.assertEqual(all_models.Workflow.INACTIVE, self.workflow.status) self.assertEqual(all_models.Workflow.INACTIVE, group.cycle.workflow.status) generate_cycle_tasks_notifs() for task in self.tasks: self.assert_notifications_for_object(task) self.assert_notifications_for_object(self.cycle, u"all_cycle_tasks_completed", u'manual_cycle_created') self.assert_notifications_for_object(group.cycle, u"all_cycle_tasks_completed", u'manual_cycle_created')
def generate_wf_tasks_notifications(_): """Generate notifications for wf cycle tasks.""" common.generate_cycle_tasks_notifs() return app.make_response(("success", 200, [("Content-Type", "text/html")]))
def test_update_tasks_from_2_cycles(self): """Test bulk update few cycles at the same time.""" with factories.single_commit(): _, _, group, _ = self._create_cycle_structure() group_id = group.id all_models.Cycle.query.update({ all_models.Cycle.is_verification_needed: False }) db.session.commit() self.tasks = all_models.CycleTaskGroupObjectTask.query.order_by( all_models.CycleTaskGroupObjectTask.id ).all() # all tasks in assigned state self.assertEqual([self.ASSIGNED] * 6, [t.status for t in self.tasks]) # all tasks in progress state self.assert_status_over_bulk_update([self.IN_PROGRESS] * 6, [self.IN_PROGRESS] * 6) group = all_models.CycleTaskGroup.query.get(group_id) self.assertEqual(self.IN_PROGRESS, self.group.status) self.assertEqual(self.IN_PROGRESS, group.status) self.assertEqual(self.IN_PROGRESS, self.cycle.status) self.assertEqual(self.IN_PROGRESS, group.cycle.status) self.assertEqual(all_models.Workflow.ACTIVE, self.workflow.status) self.assertEqual(all_models.Workflow.ACTIVE, group.cycle.workflow.status) # update 1 task to finished self.assert_status_over_bulk_update( [self.FINISHED], [self.FINISHED] + [self.IN_PROGRESS] * 5) group = all_models.CycleTaskGroup.query.get(group_id) self.assertEqual(self.IN_PROGRESS, self.group.status) self.assertEqual(self.IN_PROGRESS, group.status) self.assertEqual(self.IN_PROGRESS, self.cycle.status) self.assertEqual(self.IN_PROGRESS, group.cycle.status) self.assertEqual(all_models.Workflow.ACTIVE, self.workflow.status) self.assertEqual(all_models.Workflow.ACTIVE, group.cycle.workflow.status) generate_cycle_tasks_notifs() self.assert_notifications_for_object(self.tasks[0]) for task in self.tasks[1:]: self.assert_notifications_for_object(task, u'cycle_task_due_in', u'cycle_task_due_today', u'cycle_task_overdue', u'manual_cycle_created') self.assert_notifications_for_object(self.group.cycle, u'manual_cycle_created') self.assert_notifications_for_object(group.cycle, u'manual_cycle_created') # all tasks moved to finished self.assert_status_over_bulk_update([self.FINISHED] * 6, [self.FINISHED] * 6) group = all_models.CycleTaskGroup.query.get(group_id) self.assertEqual(self.FINISHED, self.group.status) self.assertEqual(self.FINISHED, group.status) self.assertEqual(self.FINISHED, self.cycle.status) self.assertEqual(self.FINISHED, group.cycle.status) self.assertEqual(all_models.Workflow.INACTIVE, self.workflow.status) self.assertEqual(all_models.Workflow.INACTIVE, group.cycle.workflow.status) generate_cycle_tasks_notifs() for task in self.tasks: self.assert_notifications_for_object(task) self.assert_notifications_for_object(self.cycle, u"all_cycle_tasks_completed", u'manual_cycle_created') self.assert_notifications_for_object(group.cycle, u"all_cycle_tasks_completed", u'manual_cycle_created')
def generate_wf_tasks_notifications(_): """Generate notifications for wf cycle tasks.""" common.generate_cycle_tasks_notifs() return app.make_response(("success", 200, [("Content-Type", "text/html")]))